面向对象技术强调在软件开发过程中面向客观世界或问题域中的事物,采用人类在认识客观世界的过程中普遍运用的思维方法,直观、自然地描述客观世界中的有关事物。面向对象技术的基本特征主要有抽象性、封装性、继承性和多态性。
抽象性
把众多的事物进行归纳、分类是人们在认识客观世界时经常采用的思维方法,“
物以类聚,人以群分”就是分类的意思,分类所依据的原则是抽象。抽象(Abstract)就是忽略事物中与当前目标无关的非本质特征,更充分地注意与当前目标有关的本质特征。从而找出事物的共性,并把具有共性的事物划为一类,得到一个抽象的概念。例如,在设计一个学生成绩管理系统的过程中,考察学生
张华这个对象时,就只关心他的班级、学号、成绩等,而忽略他的身高、体重等信息。因此,抽象性是对事物的抽象概括描述,实现了客观世界向计算机世界的转化。将客观事物抽象成对象及类是比较难的过程,也是
面向对象方法的第一步。例如,将学生抽象成对象及类的过程。
封装性
封装(Encapsulation)就是把对象的属性和行为结合成一个独立的单位,并尽可能隐蔽对象的内部细节。图1-1中的学生类也反映了封装性。封装有两个含义:一是把对象的全部属性和行为结合在一起,形成一个不可分割的独立单位。对象的属性值(除了公有的属性值)只能由这个对象的行为来读取和修改;二是尽可能隐蔽对象的内部细节,对外形成一道屏障,与外部的联系只能通过外部接口实现。
封装的
信息隐蔽作用反映了事物的相对独立性,可以只关心它对外所提供的接口,即能做什么,而不注意其内部细节,即怎么提供这些服务。例如,用陶瓷封装起来的一块
集成电路芯片,其内部电路是不可见的,而且使用者也不关心它的内部结构,只关心芯片
引脚的个数、引脚的电气参数及引脚提供的功能,利用这些引脚,使用者将各种不同的芯片连接起来,就能组装成具有一定功能的模块。
封装的结果使对象以外的部分不能随意存取对象的内部属性,从而有效地避免了外部错误对它的影响,大大减小了查错和排错的难度。另一方面,当对象内部进行修改时,由于它只通过少量的外部接口对外提供服务,因此同样减小了内部的修改对外部的影响。同时,如果一味地强调封装,则对象的任何属性都不允许外部直接存取,要增加许多没有其他意义,只负责读或写的行为。这为
编程工作增加了负担,增加了运行开销,并且使得程序显得臃肿。为了避免这一点,在语言的具体实现过程中应使对象有不同程度的可见性,进而与客观世界的具体情况相符合。
封装机制将对象的使用者与设计者分开,使用者不必知道对象行为实现的细节,只需要用设计者提供的外部接口让对象去做。封装的结果实际上隐蔽了复杂性,并提供了代码重用性,从而降低了
软件开发的难度。
继承性
客观事物既有共性,也有特性。如果只考虑事物的共性,而不考虑事物的特性,就不能反映出客观世界中事物之间的层次关系,不能完整地、正确地对客观世界进行抽象描述。运用抽象的原则就是舍弃对象的特性,提取其共性,从而得到适合一个对象集的类。如果在这个类的基础上,再考虑抽象过程中各对象被舍弃的那部分特性,则可形成一个新的类,这个类具有前一个类的全部特征,是前一个类的子集,形成一种层次结构,即继承结构。
继承(Inheritance)是一种联结类与类的
层次模型。继承性是指特殊类的对象拥有其一般类的属性和行为。
继承意味着“自动地拥有”,即特殊类中不必重新定义已在一般类中定义过的属性和行为,而它却自动地、隐含地拥有其一般类的属性与行为。继承允许和鼓励类的重用,提供了一种明确表述共性的方法。一个特殊类既有自己新定义的属性和行为,又有继承下来的属性和行为。尽管继承下来的属性和行为是隐式的,但无论在概念上还是在实际效果上,都是这个类的属性和行为。当这个特殊类又被它更下层的特殊类继承时,它继承来的和自己定义的属性和行为又被下一层的特殊类继承下去。因此,
继承是传递的,体现了大自然中特殊与一般的关系。
在软件开发过程中,继承性实现了软件模块的可重用性、独立性,缩短了开发周期,提高了软件开发的效率,同时使软件易于维护和修改。这是因为要修改或增加某一属性或行为,只需在相应的类中进行改动,而它派生的所有类都自动地、隐含地作了相应的改动。
由此可见,继承是对客观世界的直接反映,通过类的继承,能够实现对问题的深入抽象描述,反映出人类认识问题的发展过程。
多态性
面向对象设计借鉴了客观世界的多态性,体现在不同的对象收到相同的消息时产生多种不同的行为方式。例如,在一般类“几何图形”中定义了一个行为“绘图”,但并不确定执行时到底画一个什么图形。特殊类“
椭圆”和“多边形”都继承了几何图形类的绘图行为,但其功能却不同,一个是要画出一个椭圆,另一个是要画出一个多边形。这样一个绘图的消息发出后,
椭圆、多边形等类的对象接收到这个消息后各自执行不同的绘图函数。如图1-3所示,这就是多态性的表现。
具体来说,
多态性(Polymorphism)是指类中同一函数名对应多个具有相似功能的不同函数,可以使用相同的调用方式来调用这些具有不同功能的同名函数。
继承性和多态性的结合,可以生成一系列虽类似但独一无二的对象。由于继承性,这些对象共享许多相似的特征;由于多态性,针对相同的消息,不同对象可以有独特的表现方式,实现特性化的设计。
对象是一个自满足模块,它包含数据、以及数据的结构、和处理数据的功能。
在面向对象的环境,首先定义基本的对象,然后围绕这些对象建造系统。