第3章面向对象程序设计
本章导读
本章首先介绍面向对象程序设计的基本概念以及类的创建和使用,包括字段和属性的定义和使用、方法设计、构造方法及方法重载,对静态类及其成员、静态成员与实例成员的区别也做了简单介绍; 然后介绍了如何使用继承和接口的相关技术来实现多态性。此外,为了更好地使用集合类,本章也增加了泛型的内容,而委托是事件的基础,匿名方法和Lambda表达式则可以以更简洁的方式使用集合类、委托和事件,因此本章最后对委托的使用和事件的实现做了重点介绍。
面向对象程序设计(Object Oriented Programming,OOP)方法是当今主流的程序设计方法,是一种以事物为中心的编程思想,也即把所有的事物对象化,通过分析要实现的任务,将任务分派给具有各种不同特征和行为的对象去完成,最终完成程序的开发的方法。至于各种对象如何去实现则无须使用者去关注。在这里,类是面向对象的基本编程单元,通过类来创建对象,通过对象的方法来完成任务,对象之间通过消息(事件)传递来发生联系。
面向对象是相对于面向过程而言的。面向过程的程序设计方法是以过程为中心,从分析问题中得到解决问题的步骤,然后调用不同的函数来实现各个步骤,完成整个程序的开发,函数是面向过程的基本编程单元。
这里用一个例子来说明两者的区别。比如你是公司软件设计部门的经理,现在公司接到一个开发大型网站的项目,明确需求和确定架构之后,作为经理的你开始委派任务给不同职责的技术人员来完成,如让负责前台美工的小明来完成网站前台开发工作; 让负责技术开发的小东来完成后台代码的编写; 让数据库设计师小强来完成数据库规划和设计工作。至于他们是如何具体工作的,作为经理的你并不关心,只关心他们在完成任务后向你汇报。这种由调度不同职责的对象、对象之间相互沟通来完成任务的模式就是面向对象的思维模式。
而如果是面向过程的思维模式,则在接到开发项目后,你可能会首先确定需求和架构,规划好开发步骤,如首先设计数据库,然后编写功能实现代码,最后调整界面和测试,直到项目完成,都是按预先定义好的步骤有序进行。这就是以解决问题为核心,按步骤执行的过程。
面向过程与面向对象不是对立的,在面向对象方式内部,其实也包含面向过程,只是把面向过程的部分“包装”成一个个对象去实现。在上面的例子中,假如你把网站前台设计的工作“包装”成“小明”,把后台代码编写的工作“包装”成“小东”,而数据库设计的工作“包装”为“小强”……具体的工作由各个对象独立完成,那么这就是一个由“面向过程”到“面向对象”思维模式的转变。
再比如组装一台计算机,按照面向过程的思维模式就是,首先规划好一台计算机所需要的零部件,然后制定执行步骤,如: ①选购主板; ②选购CPU; ③选购硬盘和内存; ④选购机箱、键盘、鼠标; ⑤选购显示器; ⑥组装。而按照面向对象的思维模式来组装计算机可能就是: 根据要购买计算机的配置和性能,跑去计算机城装机店,对老板说,给我组装一台计算机!至于老板是怎么组装的,是他自己组装还是店员组装,你并不关心,关心的是对象(店家)帮你装好你所需要的计算机。面向过程关心的是解决问题的步骤,面向对象关心的是哪些对象可以帮助我们解决问题。
面向对象的程序开发也是如此,通过已存在的对象来构建应用程序界面以及实现所需操作,完成任务设计。如果需要的对象不存在,那么自己可以设计出来,让其具备所需功能,在需要使用的场合直接或重复调用。
面向对象程序设计方法达到了软件工程的三个主要目标: 重用性、灵活性和扩展性。封装、继承和多态性是面向对象的三大主要特征。
1. 类与对象
现实世界中实际存在的事物都可以称为对象,如一本书、一部手机、一个人等。类,即类别、类型,是对具有相同特征和行为的事物进行高度概括后建立起来的一个抽象模型。例如,所有的书籍都可以是书籍类,所有的手机都属于手机类,人归为人类等。所有相同类型的对象都具有相同的特征,如人有姓名、性别、身高和体重特征等,这些特征就是对象的属性; 而唱歌、跳舞,这些就是对象的行为或动作。
类是对对象特征和行为的描述,对象是类的实例,即按照某种类型创建出来实际的东西。
类是面向对象程序设计的基本单位,一个典型的类应包含数据和对数据的操作。数据用于描述对象的特征,而操作体现了对象具有的行为。
2. 封装
封装是实现信息隐蔽的一种手段。将数据和对数据处理的方法组合在一起,对外只提供操作接口。对用户而言,具体实现是隐藏的。正如一部电视机,对外提供操作的接口: 操作面板或遥控器。用户无须知道电视机的工作原理,也无须了解遥控信号如何发送到电视机,只要会使用就可以了。本节要学习的就是如果把功能包装(封装)起来,给用户(更多的时候是自己)提供使用接口。
3. 继承
继承的目的是在已经存在的类的基础上,保留其原有的功能,并扩展其功能,从而创建新类。在这里,已存在的类称为基类,新类称为派生类。继承的好处在于减少编码工作量、提高代码重用性,便于维护和扩展。
4. 多态性
多态性是指一个方法可以有不同的实现。不同实现的方法,共享同一接口,调用时呈现不同的(多种)结果(形态)。多态性可以通过继承、方法重载、虚方法和重写、抽象方法、接口等技术来实现,好处在于方便调用,灵活性高。
3.1类的创建与使用
3.1.1创建类
为降低学习的难度,这里只介绍最简单的类的结构。类的基本结构如下:
[访问修饰符]class类名
{
类主体;
}
说明:
(1) 访问修饰符是指类的可访问性(作用域),可选。C#的访问修饰符如表3.1所示。类的访问修饰符说明类使用的级别,一般只使用public(公共的)或internal(内部的)。默认为internal,代表仅本项目可使用的类。如果设计的类需要提供给其他项目使用,类名前必须带上public关键字,这种情况下一般以类库项目的形式出现,编译后得到以dll为扩展名的文件,在其他项目中需要添加对该dll文件的引用后方可使用。
表3.1C#中的访问修饰符
访问修饰符含义
public同一程序集中的任何其他代码或引用该程序集的其他程序集都可以访问该类型或成员private只有同一类中的代码可以访问该类成员protected只有同一类或者派生类中的代码可以访问该类型或成员internal默认值。同一程序集中的任何代码都可以访问该类型或成员,但其他程序集中的代码不可以protected internal同一程序集中的任何代码或其他程序集中的任何派生类都可以访问该类型或成员
(2) class为定义类的关键字,其后紧跟类名。类名必须满足标识符命名规则,一般采用Pascal命名规范,即类名中每个单词的首字母大写。类名后是类主体,也就是类实现代码,置于{ }内,用于定义类成员,包括类的字段、属性、方法和事件等。
注意: 所谓程序集,是指包含一个或者多个类文件和资源文件的集合。简而言之,就是一个C#项目,经编译后以可执行文件(扩展名为exe)或以动态链接库文件(扩展名为dll)的形式存在。
(3) 类主体包含数据成员和方法成员。所有在类主体的数据部分定义的变量,都是类的数据成员,或称成员变量; 所有在类主体中定义的方法都是类的方法成员。一般一个类包含数据成员和方法成员,但也可以只有数据成员,或只有方法成员。成员变量在C#中称为字段。
下面创建了一个最简单的Student类:
class Student
{
}
以上创建了一个没有任何数据成员和方法成员的空类,虽然没有意义,但满足类的构造语法。
虽然一个代码文件可以包含多个类,但规范的做法是将一个类保存在一个以类名命名的单独文件中。在Visual Studio 2010中为项目添加类文件的具体操作是: 新建项目或打开已存在项目,在“解决方案资源管理器”窗口中右击项目名称,选择“添加”→“类”命令,在打开的“添加新项”对话框中的“名称”栏中输入类名,然后单击“添加”按钮来完成操作。