购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.1 面向对象的基本概念

为了讨论面向对象(Object-Oriented,OO)的技术和方法,必须首先明确什么是“面向对象”?为什么要讨论面向对象的方法?什么是对象?对于这些问题,有许多不同的看法。其中Booch、Coad/Yourdon和Jacobson的方法在面向对象软件开发界得到了广泛的认可。特别值得一提的是统一建模语言(UML,Unified Modeling Language),该方法结合了Booch、OMT和Jacobson方法的优点,统一了符号体系,并从其他的方法和工程实践中吸收了许多经过实践检验的概念和技术。

Peter Coad和Edward Yourdon曾提出了下列等式:

面向对象=对象(Objects)+类(Classes)+继承(Inheritance)+消息通信(Communication with Messages)

4.1.1 对象与封装

对象(Object)是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。面向对象的软件系统是由对象组成的,复杂的对象由比较简单的对象组合而成。也就是说,面向对象方法学使用对象分解取代了传统方法的功能分解。

对象三要素:对象标志、属性和服务。

对象标志(Object Identifier),也就是对象的名字,供系统内部唯一地识别对象。 定义或使用对象时,均应指定对象标志。

属性(Attribute),也称状态(State)或数据(Data),用来描述对象的静态特征。 在某些面向对象的程序设计语言中,属性通常被称为成员变量(Member Variable)或简称变量(Variable)。

服务(Service),也称操作(Operation)、行为(Behavior)或方法(Method)等,用来描述对象的动态特征。 在某些面向对象的程序设计语言中,服务通常被称为成员函数(Member Function)或简称函数(Function)。

封装(Encapsulation)是对象的一个重要原则。它有两层含义:第一,对象是其全部属性和全部服务紧密结合而形成的一个不可分割的整体;第二,对象是一个不透明的黑盒子,表示对象状态的数据和实现操作的代码都被封装在黑盒子里面。使用一个对象的时候,只需知道它向外界提供的接口形式,无须知道它的数据结构细节和实现操作的算法。从外面看不见,也就更不可能从外面直接修改对象的私有属性了。

4.1.2 类与类库

类(class)是对象的抽象定义,是一组具有相同数据结构和相同操作的对象的集合。类的定义包括一组数据属性和在数据上的一组合法操作。类定义可以视为一个具有类似特性与共同行为的对象的模板,可用来产生对象。

类与对象是抽象描述与具体实例的关系,一个具体的对象被称为类的一个实例(Instance)。它们都可使用类中提供的函数。一个对象的状态则包含在它的实例变量中。

从物理特征上来看,类库和传统例程库是类似的,它们都是一种预先定义的程序库。类库是一种预先定义的程序库,它以程序模块的形式,按照类层次结构把一组类的定义和实现组织在一起。较上层的类代表了较一般的事物,相反,较下层的类代表了较具体的事物,很好地体现了面向对象机制的继承性、重载等许多特征。

类属类(Generic Class)仅描述了适用于一组类型的通用样板,由于其中所处理对象的数据类型尚未确定,因而程序员不可用类属类直接创建对象实例,即一个类属类并不是一种真正的类类型。

类属类必须经过实例化后才能成为可创建对象实例的类类型。类属类的实例化是指用某一数据类型替代类属类的类型参数。类属类定义中给出的类型参数称为形式类属参数,类属类实例化时给出的类型参数称为实际类属参数。如果类属类实例化的实际类属参数可以是任何类型,那么这种类属类称为无约束类属类。然而在某些情况下,类属类可能要求实际类属参数必须具有某些特殊的性质,以使得在类属类中可应用某些特殊操作,这种类属类称为受约束类属类。类属类对类库的建设提供了强有力的支持。

4.1.3 继承与多态

继承(Inheritance)是使用已存在的定义作为基础建立新定义的技术,继承是面向对象方法学中的一个十分重要的概念。新类的定义可以是现存类所声明的数据、定义与新类所增加的声明的组合。新类复用现存类的定义,而不要求修改现存类。因为这种类的一部分已经实现和测试,故开发费用较少。现存类可当作父类(泛化类、基类或超类)来引用,则新类相应地可当作子类(特化类、子女类或派生类)来引用。

在面向对象技术中,多态考虑的是类与类之间的层次关系,以及类自身内部特定成员函数之间的关系问题,是解决功能和行为的再抽象问题。多态是指类中具有相似功能的不同函数是用同一个名称来实现,从而可以使用相同的调用方式来调用这些具有不同功能的同名函数。这也是人类思维方式的一种直接模拟,比如一个对象中有很多求两个数最大值的行为,虽然可以针对不同的数据类型,写很多不同名称的函数来实现,但事实上,它们的功能几乎完全相同。这时,就可以利用多态的特征,用统一的标志来完成这些功能。这样,就可以达到类的行为的再抽象,进而统一标志,减少程序中标志符的个数。

严格地说,多态性可分为四类,分别为过载多态(重载多态),强制多态,包含多态和参数多态,其中前两种统称为专用多态(特定多态),后面两种称为通用多态。

包含多态是研究类族中定义于不同类中的同名成员函数的多态行为,主要是通过虚函数来实现。包含多态最常见的例子就是子类型化,即一个类型是另一类型的子类型。

参数多态的应用比较广泛,被称为最纯的多态。这是因为同一对象、函数或过程能以一致的形式用于不同的类型。参数多态与类属(类模板)相关联,类属是一个可以参数化的模板,其中包含的操作所涉及的类型必须用类型参数实例化。这样,由类模板实例化的各类都具有相同的操作,而操作对象的类型却各不相同。

过载多态是同一算子(操作符、函数名等)被用来表示不同的功能,通过上下文以决定一个算子所代表的功能,即通过语法对不同语义的对象使用相同的算子,编译能够消除这一模糊。

强制多态是通过语义操作把一个变元的类型加以变换,以符合一个函数的要求,如果不做这一强制性变换将出现类型错误。类型的变换可在编译时完成,通常是隐式地进行,当然也可以在动态运行时来做。

从实现的角度来看,多态可划分为两类,分别是编译时的多态和运行时的多态。前者是在编译的过程中确定了同名操作的具体操作对象,而后者则是在程序运行过程中才动态地确定操作所针对的具体对象。这种确定操作的具体对象的过程就是联编(编联,束定或绑定)。联编是指计算机程序自身彼此关联的过程,也就是把一个标志符名和一个存储地址联系在一起的过程。用面向对象的术语讲,就是把一条消息和一个对象的方法相结合的过程。

按照联编进行的阶段的不同,可以分为两种不同的联编方法,分别为静态联编和动态联编,这两种联编过程分别对应着多态的两种实现方式。

联编工作在编译连接阶段完成的情况称为静态联编。因为联编过程是在程序开始执行之前进行的,因此有时也称为早期联编或前联编。在编译和连接过程中,系统就可以根据类型匹配等特征确定程序中操作调用与执行该操作代码的关系,其确定了某一个同名标志到底是要调用哪一段程序代码。有些多态类型,其同名操作的具体对象能够在编译、连接阶段确定,通过静态联编解决,比如过载,强制和参数多态等。

与静态联编相对应,联编工作在程序运行阶段完成的情况称为动态联编,也称为晚期联编或后联编。在编译、连接过程中无法解决的联编问题,要等到程序开始运行之后再来确定,包含多态的操作对象的确定就是通过动态联编完成的。

4.1.4 消息通信

消息(Message)是指向对象发出的服务请求,它应该含有下述信息:提供服务的对象标志、消息名、输入信息和回答信息。对象与传统的数据有本质区别,它不是被动地等待外界对它施加操作,相反,它是进行处理的主体,必须发消息请求它执行它的某个操作,处理它的私有数据,而不能从外界直接对它的私有数据进行操作。

消息通信(Communication with Messages)也是面向对象方法学中的一条重要原则,它与对象的封装原则密不可分。封装使对象成为一些各司其职、互不干扰的独立单位;消息通信则为它们提供了唯一合法的动态联系途径,使它们的行为能够互相配合,构成一个有机的系统。

只有同时使用对象、类、继承与消息通信,才是真正面向对象的方法。

4.1.5 面向对象方法学的优点

与面向过程相比,面向对象方法学具有以下优点。

(1)与人类习惯的思维方法一致: 面向对象方法学的出发点和基本原则,是尽可能模拟人类习惯的思维方式,使软件开发的方法与过程尽可能接近人类认识世界解决问题的方法与过程,也就是使描述问题的“问题域”与解决问题的“解域”在结构上尽可能一致。

(2)稳定性好: 传统的软件开发方法基于功能分析与功能分解,软件结构紧密依赖于系统所要完成的功能,当功能需求发生变化时将引起软件结构的整体修改。由于用户需求变化大部分是针对功能的,因此这样的系统是不稳定的。

面向对象的方法用对象模拟问题域中的实体,以对象为中心构造软件系统,当系统的功能需求变化时并不会引起软件结构的整体变化。由于现实世界中的实体是相对稳定的,因此以对象为中心构造的软件系统也是比较稳定的。

(3)可重用性好: 面向对象方法学在利用可重用的软件成分构造新的软件系统时有很大的灵活性。继承机制与多态性使得子类不仅可以重用其父类的数据结构与程序代码,并且可以方便地修改和扩充,而这种修改并不影响对原有类的使用。

(4)较易开发大型软件产品: 由于用面向对象方法学开发软件时,构成软件系统的每个对象相对独立。因此,可以把一个大型软件产品分解成一系列相互独立的小产品来处理。这不仅降低了开发的技术难度,而且也使得对开发工作的管理变得容易多了。

(5)可维护性好: 面向对象的软件比较容易理解、容易修改、容易测试。 XqkKlugb6h8FFNP7N+NivVMYnwUvVmmGFUB79hZ1eBIt8QVNEyk/nN6Cl7E3sd5k

点击中间区域
呼出菜单
上一章
目录
下一章
×