

不同对象(物体)之间的相互作用和通信构成了完整的现实世界。就像人们按照现实世界这个本来面貌来理解世界一样,我们直接通过对象及其相互关系来反映世界。这样建立起来的系统才能符合现实世界的本来面目。
C#是一种安全、稳定的面向对象的语言。为了更好、更有效地使用C#编程技术,需要理解和掌握面向对象的基本概念和特点。

在生活中,经常有“这个东西(或物体)”、“那个东西(或物体)”的说法,话中所指的“东西(或物体)”就是指的对象。对象是描述客观事物的一个实体,几乎任何东西都可以看成是对象。对象可以是有形的,如一辆车、一个纳美人、一份文件、阿凡达男主角杰克、女主角奈蒂莉;也可以是无形的,如一个方案、一项计划等。
程序中的对象来源于生活,现实生活中的某个实体经过抽象、建模后就变成程序中的一个对象,即用特定符号描述的对象。现实生活中的某个实体往往有自己的特性和行为,例如,一个纳美人,其特性有姓名、性别、手指数、尾巴长度等,其行为有吃、喝、走、说和战斗等。如果将之写入程序中,那么如何去描述这些特性和操作呢?如图5.1(a)和 图5.1(b)所示。我们可以用具体的信息描述每一个纳美人对象。
不难发现程序中的对象与纳美人有着相同的结构模型,如图5.1(c)所示。“奈蒂莉”和“苏泰”这两个纳美人对象都包括对象名、一组属性、一组操作,其中属性描述对象的属性特征表示对象的状态,是类的数据成员;操作(或称方法)描述对象的行为,是对象的行为特征通常是对数据成员进行操作的方法。
然后进一步抽象提炼,就可以得出所有类的结构模型,如图5.1(d)所示。
在面向对象编程中,一个程序可以看作是对象之间相互作用的结果。

|
| 图5.1 对象模型与类模型 |
由于对象与现实世界的实体有如此紧密的联系,所以面向对象的程序设计思想更加贴近于人们的思维和习惯。


现实生活中的对象往往可以根据共性对其进行归类,一组具有共同特征和行为的相似对象归为一类。例如,鱼类是一个类,它们的共性为:有脊椎、终生生活在水里、用鳃呼吸、用鳍游泳等,一条具体的鱼则是一个对象。在程序设计中,把一组相似对象的共同特征抽象出来并存储在一起,就形成了类。每条鱼都具有鱼类所规定的特性和行为,但是,每条鱼都拥有自己独有的东西,在程序中,即是具体属性值各不相同。再如,VS.NET工具箱里面的按钮控件类是一个类,每一个具体的按钮都是按钮控件类的一个对象,它们的共性是都有大小、颜色、字体等属性以及单击事件等行为,但除了共性,每一个具体的按钮各自有不同的大小、颜色和字体。
类是对事物的概括性定义,而对象是事物本身,是类的一个实例(instance),对象具有类所规定的特征,只能执行类所规定的操作。打个比方,类就相当于一个模板,而对象则是由这个模板产生出来的具体产品,一个模板可以生产很多产品,一个类可以产生很多对象。例如,VS.NET工具箱中存放了很多控件类,其中有按钮控件类,当在窗体上添加一个按钮时,就是由按钮类创建了一个按钮对象,当往窗体添加多个按钮时,就是由按钮类创建出多个按钮对象。
从具体对象到类实际上是一个概括的过程,把对象的共同特征抽取出来,形成了类,如果再对这个类用计算机语言加以描述,就形成了程序中的类,这个过程称为抽象。抽象包括数据抽象和行为抽象,因此程序中类的结构模型与对象模型一样,包含3个部分:类名、属性和操作,如图5.1(d)所示。
对象的特征和行为往往有很多,怎样从复杂的信息中抽象出符合要求的有用信息是一个非常重要的工作,例如,要建立学生类,学生有姓名、学号、班级、各门课成绩、总成绩、联系电话、家庭住址、父母姓名等信息,并非所有的这些信息都是所需要的,怎样抽取有用信息呢?应该根据所开发软件的具体需求而设计,例如,如果开发学生成绩管理软件,那么姓名、学号、班级、各门课成绩、总成绩是有用信息,如果开发学生档案管理软件,关心的就是学生姓名、学号、班级、联系电话、家庭住址、父母姓名等信息。因此同样是学生,在不同的软件系统中其具体属性与行为构成可以根据需求的不同而不同。
头脑风暴:
1.《阿凡达》中有哪些类?
2.“贪吃蛇”游戏中有哪些类?
3.“纳美人”类可以有哪些属性和方法?


人们在使用生活用品时往往只知道如何使用,而不需要了解其内部实现细节。例如,对于洗衣机,使用者可以通过面板上的按键或按钮进行操纵,选择好洗涤衣物种类后,按下面板上的开始键,洗衣机就自动完成洗涤、甩干等一系列操作,至于洗衣机内部芯片如何完成指定操作,对于使用者来说是黑盒子,不需要知道,这种把对象的数据和操作细节向外部隐藏起来的方法就是面向对象中的封装性和数据隐藏。
封装实际上是在类的设计过程中完成的,类对外部提供统一的接口方法,类的内部相当于一个黑盒,类的使用者并不知道类的内部实现细节,只要知道怎么调用这些接口方法就够了。封装的好处主要有两个方面:一是提供了安全机制,隐藏了数据和操作实现细节,并通过设置访问权限拒绝了一切没有定义过的访问形式;二是降低了软件的复杂性,如果类内部的代码被修改,只要对外的接口不变,对类的使用者就丝毫没有影响。例如,很多人家中都经历过电视机的更新换代,不同类型的电视机其内部实现会有所不同,但是电视机外接口基本没变,即用户操纵电视机的方式不受影响,这样就大大地方便了使用者。
一起来看一则幽默:如果还有人问换一个电灯泡需要几个程序员?那这个人还在用面向过程的思维考虑问题。一个设计良好的电灯泡类必然封装了换灯泡的方法,所以你要做的就是调用“换电灯泡”的方法。

现实世界中有很多事物之间存在一般化与特殊化的关系,这都是由于事物之间存在着“继承”关系。交通工具与汽车、飞机、轮船、火车之间,电视机与液晶电视机、等离子电视机、背投电视机之间都存在一种一般化与特殊化的关系。一般化的事物具有特殊化事物的共同特征,特殊化的事物具有一般化事物的所有特征,并发展了自己的特有特征。这种思想反映在程序设计中,就是继承,即一个类从另一个类获得了已有的基本特征,并在此基础上增加了自身的一些特殊特征。例如,已有一个交通工具类,想要再定义一个汽车类,因为汽车是交通工具的一种,具备交通工具的所有特征(例如,可以载人、载物),所以可以让汽车类继承交通工具类的所有特征,在此基础上再添加自己的新特征(例如,在公路上行驶)。汽车类继承交通工具类,交通工具类派生出汽车类。
类的继承与派生使用户可以重用前人或自己已有的代码,使自己的开发工作站在前人的肩膀上,从而实现代码的重用。而且通过继承机制实现了现实生活中事物间的一般化与特殊化的关系,使编程思想更贴近人们的日常思维。

有一种智能洗衣机,能根据放入的衣物材料质地自动判断采用哪种洗衣程序,例如,如果用户放入棉布类衣物后按“开始”键,洗衣机会启动棉布类衣物的洗衣程序,采用较大的洗涤力度和较长的洗涤时间;如果用户放入丝绸衣物后按“开始”键,洗衣机会启动丝绸类衣物的洗衣程序,进行轻柔洗涤并加上除皱功能,洗涤时间也较短。同样是“洗衣”的功能(方法),却能针对不同的对象(参数)实现不同的洗涤过程(程序内容)和洗涤效果(返回值),这种现象就是多态。
在面向对象程序设计中,多态是指用户对一个对象进行一个操作,但具体的动作却取决于这个对象的类型,即对不同的对象执行相同的操作会产生不同的结果。如果将厨师定义成一个类,将炒菜定义成其中的一个方法,那么该方法可针对不同的作料和作料种类炒出不同味道的菜肴。所以,炒菜的操作就是一种多态。
从多态发生的时机上分,多态可以分为编译时多态和运行时多态两种。这个将会在后面章节详述。

对象具有一定的独立性和自治性,但对象和对象之间不是彼此独立的,它们通过消息进行通信,一个程序可以被看作是对象之间相互作用的结果。例如,要完成某项任务,需要向相关对象发送消息,请求它们执行相应的操作,然后由这些操作返回所需的结果或改变对象的状态。
以上是对面向对象的几个特征的简单介绍,大家可以结合后续的学习逐渐加以体会、加深理解。