面向对象技术 (Object-Oriented Technology)
面向对象技术强调在软体开发过程中面向客观世界或问题域中的事物,採用人类在认识客观世界的过程中普遍运用的思维方法,直观、自然地描述客观世界中的有关事物。面向对象技术的基本特徵主要有抽象性、封装性、继承性和多态性。
基本介绍
- 中文名:面向对象技术
- 外文名:Object-Oriented Technology
- 类型:科学
- 性质:抽象性、封装性、继承性和多态性
分析方法
面向对象的分析方法是利用面向对象的信息建模概念,如实体、关係、属性等,同时运用封装、继承、多态等机制来构造模拟现实系统的方法。
传统的结构化设计方法的基本点是面向过程,系统被分解成若干个过程。而面向对象的方法是採用构造模型的观点,在系统的开发过程中,各个步骤的共同的目标是建造一个问题域的模型。在面向对象的设计中,初始元素是对象,然后将具有共同特徵的对象归纳成类,组织类之间的等级关係,构造类库。在套用时,在类库中选择相应的类。
特徵
抽象性
把众多的事物进行归纳、分类是人们在认识客观世界时经常採用的思维方法,“物以类聚,人以群分”就是分类的意思,分类所依据的原则是抽象。抽象(Abstract)就是忽略事物中与当前目标无关的非本质特徵,更充分地注意与当前目标有关的本质特徵。从而找出事物的共性,并把具有共性的事物划为一类,得到一个抽象的概念。例如,在设计一个学生成绩管理系统的过程中,考察学生张华这个对象时,就只关心他的班级、学号、成绩等,而忽略他的身高、体重等信息。因此,抽象性是对事物的抽象概括描述,实现了客观世界向计算机世界的转化。将客观事物抽象成对象及类是比较难的过程,也是面向对象方法的第一步。例如,将学生抽象成对象及类的过程。
封装性
封装(Encapsulation)就是把对象的属性和行为结合成一个独立的单位,并儘可能隐蔽对象的内部细节。图1-1中的学生类也反映了封装性。封装有两个含义:一是把对象的全部属性和行为结合在一起,形成一个不可分割的独立单位。对象的属性值(除了公有的属性值)只能由这个对象的行为来读取和修改;二是儘可能隐蔽对象的内部细节,对外形成一道屏障,与外部的联繫只能通过外部接口实现。
封装是通过限制只有特定类的对象可以访问这一特定类的成员,而它们通常利用接口实现讯息的传入传出。举个例子,接口能确保幼犬这一特徵只能被赋予狗这一类。通常来说,成员会依它们的访问许可权被分为3种:公有成员、私有成员以及保护成员。有些语言更进一步:Java可以限制同一包内不同类的访问;C#和VB.NET保留了为类的成员聚集準备的关键字:internal(C#)和Friend(VB.NET);Eiffel语言则可以让用户指定哪个类可以访问所有成员。
封装的信息隐蔽作用反映了事物的相对独立性,可以只关心它对外所提供的接口,即能做什幺,而不注意其内部细节,即怎幺提供这些服务。例如,用陶瓷封装起来的一块积体电路晶片,其内部电路是不可见的,而且使用者也不关心它的内部结构,只关心晶片引脚的个数、引脚的电气参数及引脚提供的功能,利用这些引脚,使用者将各种不同的晶片连线起来,就能组装成具有一定功能的模组。
封装的结果使对象以外的部分不能随意存取对象的内部属性,从而有效地避免了外部错误对它的影响,大大减小了查错和排错的难度。另一方面,当对象内部进行修改时,由于它只通过少量的外部接口对外提供服务,因此同样减小了内部的修改对外部的影响。同时,如果一味地强调封装,则对象的任何属性都不允许外部直接存取,要增加许多没有其他意义,只负责读或写的行为。这为编程工作增加了负担,增加了运行开销,并且使得程式显得臃肿。为了避免这一点,在语言的具体实现过程中应使对象有不同程度的可见性,进而与客观世界的具体情况相符合。
封装机制将对象的使用者与设计者分开,使用者不必知道对象行为实现的细节,只需要用设计者提供的外部接口让对象去做。封装的结果实际上隐蔽了複杂性,并提供了代码重用性,从而降低了软体开发的难度。
继承性
客观事物既有共性,也有特性。如果只考虑事物的共性,而不考虑事物的特性,就不能反映出客观世界中事物之间的层次关係,不能完整地、正确地对客观世界进行抽象描述。运用抽象的原则就是捨弃对象的特性,提取其共性,从而得到适合一个对象集的类。如果在这个类的基础上,再考虑抽象过程中各对象被捨弃的那部分特性,则可形成一个新的类,这个类具有前一个类的全部特徵,是前一个类的子集,形成一种层次结构,即继承结构。
继承(Inheritance)是一种联结类与类的层次模型。继承性是指特殊类的对象拥有其一般类的属性和行为。继承意味着“自动地拥有”,即特殊类中不必重新定义已在一般类中定义过的属性和行为,而它却自动地、隐含地拥有其一般类的属性与行为。继承允许和鼓励类的重用,提供了一种明确表述共性的方法。一个特殊类既有自己新定义的属性和行为,又有继承下来的属性和行为。儘管继承下来的属性和行为是隐式的,但无论在概念上还是在实际效果上,都是这个类的属性和行为。当这个特殊类又被它更下层的特殊类继承时,它继承来的和自己定义的属性和行为又被下一层的特殊类继承下去。因此,继承是传递的,体现了大自然中特殊与一般的关係。
在软体开发过程中,继承性实现了软体模组的可重用性、独立性,缩短了开发周期,提高了软体开发的效率,同时使软体易于维护和修改。这是因为要修改或增加某一属性或行为,只需在相应的类中进行改动,而它派生的所有类都自动地、隐含地作了相应的改动。
由此可见,继承是对客观世界的直接反映,通过类的继承,能够实现对问题的深入抽象描述,反映出人类认识问题的发展过程。
当一个类从多个父类继承时,我们称之为“多重继承”。如一只狗既是吉娃娃犬又是牧羊犬(虽然事实上并不合逻辑)。多重继承并不总是被支持的,因为它很难理解,又很难被好好使用。
多态性
面向对象设计借鉴了客观世界的多态性,体现在不同的对象收到相同的讯息时产生多种不同的行为方式。例如,在一般类“几何图形”中定义了一个行为“绘图”,但并不确定执行时到底画一个什幺图形。特殊类“椭圆”和“多边形”都继承了几何图形类的绘图行为,但其功能却不同,一个是要画出一个椭圆,另一个是要画出一个多边形。这样一个绘图的讯息发出后,椭圆、多边形等类的对象接收到这个讯息后各自执行不同的绘图函式。如图1-3所示,这就是多态性的表现。
具体来说,多态性(Polymorphism)是指类中同一函式名对应多个具有相似功能的不同函式,可以使用相同的调用方式来调用这些具有不同功能的同名函式。
继承性和多态性的结合,可以生成一系列虽类似但独一无二的对象。由于继承性,这些对象共享许多相似的特徵;由于多态性,针对相同的讯息,不同对象可以有独特的表现方式,实现特性化的设计。
面向对象技术使软体的开发超越了过程式编程,而进入了简化应用程式开发的可重用编程世界。不象旧的编程方式,当程式的体积增长时,程式维护和调试并不变得更複杂。对象技术在两个级别发挥作用:
在数据级别,对象技术可以集成一个机构中的许多不同类型的信息,过去的信息已经不再兼容了。
在程式开发级别,对象技术提供模组化程式构造,这时,程式设计师在现有对象的基础之上进行开发。对象可以被其他对象再使用,以利用它们的过程,从而消除了当再次需要它们的时候,必须每次都重写这些代码。
由于无需改变或分解整个系统,所以再设计或扩展系统是很容易的。实际上,是放弃或修改这些模组,并且增加新的模组以提供增强的功能。
一个对象是一个完整的数据分组,它包括对数据进行处理的功能。在一个面向对象的环境,对象的数目是数不清的。它们可能包括一个资料库的记录、一个档案、一个物理资源、甚至是一个用户(它是用户的登录帐户)。为了使开发人员使用面向对象编程语言工作,对象是一个自满足模组,它包含数据、以及数据的结构、和处理数据的功能。
对象可以是下面情况的任何之一:
在一个面向对象作业系统中实现一个进程的代码,例如验证安全许可权。
程式设计师和开发人员用于彙编程式的预定义代码模组。
来自一个应用程式的数据块,如一个绘图程式、电子表格或多媒体工具。
在一个资料库中的对象,例如库存条目或顾客。
在一个面向对象的资料库中,对象可以代表跟蹤的商务中的实际实体,例如生产的产品、库存、顾客和厂商。相应地,在面向对象的作业系统中,对象也是一些实体,如档案、设备和用户,或构成一个複合文档的实体数据块。在面向对象的环境,首先定义基本的对象,然后围绕这些对象建造系统。
有许多潜在对象,并且它们可以归化到定义不同类型对象的层次化类(hierarchical classes)。父类可以对子类传递特性。让我们来考虑一个类“people”,它拥有两个子类“male”和“female”。这些子类又可以拥有它们自己的子类,如图O-3所示。每个子类都有从它的父亲处继承来的综合特徵,以及它们自己的专有特徵。另外,一些继承来的特徵由于它们对子类不合适,而会被阻挡。
这和计算机如何关联昵?记住,我们在讨论存储许多不同数据类型,和访问许多不同类型应用程式数据的途径。通过按这种方式对数据分类,我们可以在一个对象内,直接包括进行抽取、显示、合併和列印的过程数据。如果需要,对数据进行分类,可以简化构造过程和改造(revision)过程。例如,一个数据块对象可能包括一个对这些数据按特定的方式进行排序的过程,它可以被许多不同的使用这个数据的应用程式所激活。
对象类和对象实例
对象类 一个类定义了一组对象。类具有行为(be-havoir),它描述一个对象能够做什幺以及做的方法(method),它们是可以对这个对象进行操作的程式和过程。
对象实例 一个对象是一个类的一个实例,它代表一个现实物理“事件”,例如在一个财物系统资料库中的一个顾客或一个库存部分。类的继承(class inheritance)是一个重要的概念,它为一个子类继承它的父类的内置描述提供了途径。在父类中使用的代码被向下传给这个类指定的一个类(子类)。
例如,一个面向对象的资料库可以有一个称为“client”的类,这个类有两个子类,分别称为“company”和“individual”。首先,创立称为“client”的对象。它包含一个结构和一些过程,这些过程处理数据和从对象之外获得信息。然后,company和individual对象作为client的子类进行定义。作为一个子类,它们继承client对象的结构和特徵,但是这些特徵中的一些可能被禁止,或可以增加一些附加特徵。例如,company子类可以具有一个特定的折算,而individua1子类却不具有。如果你需要一个关于客户的列表,你可以请求client对象进行列表。然而,如果你希望知道客户的账目平衡,你就需要从每个包含客户平衡的子类对象获得信息。
对象包含数据和过程,并且当被请求时提供信息。想像一个包含数据的箱子,它有一些按钮,你可以按这些按钮来对数据运行过程。方法是,一些对对象进行操作的过程或程式,它们可以使对象根据对象的内部代码和结构来以特定的形式进行动作。相似地,可以对对象的不同的类进行操作。有一个概念称为多态性(poly-morphism)或重载(overloading)。使用多态性,一组通用的方法可以在很大範围的类上进行操作。然而,具有相同名字和称呼的方式却可能诱发不同的事情。例如,在文本数据的“next”导致游标跳到下一个工作,而在电子表格的“next”却导致游标跳到下一个单元。
对象通过传送讯息与另一个对象对话。这些讯息在本质上是通过按下对象上的“按钮”从对象请求过程。在一个网路环境,你可以查看和讯息汇流排相连的对象,如图O-4所示。讯息传递为对象在一个面向对象的分散式计算环境进行通信提供了一条有效途径。讯息传递是一种存储再转发方式,就象在电子函件系统中使用的那样。讯息被从一台计算机传送到另一台计算机,直到它们抵达目的地。
所有这些都加到软体中,它们易于维护,并且在连续的基础之上改进,即无需对整个系统进行重新设计。
对象是可重用的,使得系统增长时,它易于加入系统,这是因为在现有对象中的代码对创造新的对象是可重用的。
对象系统是可扩展的,开发人员增加模组,而模组重用内置数据结构,无需重编译作业系统。
易于建造系统,这是因为面向对象对设计系统和实现系统提供了一条很自然的途径。
对象可以提供了一种通用接口,因而许多不同应用程式能够访问数据。
也有许多不利的方面,包括大量增加了前端设计的时间,减低了性能和技术的不成熟。然而,随着系统的成长和硬体的不断强大,这些不利可以减退。这些缺陷,在对象系统可以在遍布分布网路上的许多不同类型的系统上向用户提供数据这一事实面前,也会减少。
Objects in Distributed Environments 分散式环境中的对象
对象技术被认为对实现未来的分散式系统是很有生命力的。这样,系统的複杂性可以通过实现讯息传递服务(如对象请求代管器)的模型而简化。对象只是简单地请求服务,并且其他对象提供这些服务。开发人员不需要更多地知道对象将在上面通信的系统情况。事实上,对象技术为局部使用、将来扩展到异构分散式环境、设计套用提供了途径。
在这一领域的发展包括:
对象管理组织(OMG)的公用对象请求代管器体系结构(CORBA)是一种规範,它的设计是为对象产生和接收请求提供了途径。
Microsoft的对象连结和嵌入(OLE),为在单一台式系统或一个网路上的应用程式共享数据提供了一条途径。
IBM的系统对象模型(SOM)和分散式系统对象模型(DSOM)提供了低级对象语言
OpenDoc是一种为共享文本、图形和多媒体对象,而由Apple、Borland、IBM、Novel1和WordPerfect等公司开发的开发环境。
相关条目:Cario;Common Object Model 公用对象模型;Common Object Request Broker Architecture 公用对象请求代管器体系结构;Compound Documents 複合文档;Object Broker,DEC DEC的Object Broker;Object Linking and Embedding对象连结和嵌入;Object Management Architecture对象管理体系结构;Object-Oriented Interfaces and Operating Systems面向对象的接口和作业系统;Object Request Broker 对象请求代管器;Workplace OS。
面向对象与面向过程的区别
面向对象技术是一种以对象为基础,以事件或讯息来驱动对象执行处理的程式设计技术。它以数据为中心而不是以功能为中心来描述系统,数据相对于功能而言具有更强的稳定性。它将数据和对数据的操作封装在一起,作为一个整体来处理,採用数据抽象和信息隐蔽技术,将这个整体抽象成一种新的数据类型——类,并且考虑不同类之间的联繫和类的重用性。类的集成度越高,就越适合大型应用程式的开发。另一方面,面向对象程式的控制流程由运行时各种事件的实际发生来触发,而不再由预定顺序来决定,更符合实际。事件驱动程式的执行围绕讯息的产生与处理,靠讯息循环机制来实现。在实际编程时可以採用搭积木的方式来组织程式,站在“巨人”的肩上实现自己的目标。面向对象程式的设计方法使得程式结构清晰、简单,提高了代码的重用性,有效减少了程式的维护量,提高了软体的开发效率。
在结构上,面向对象程式与面向过程程式有很大不同。面向对象程式由类的定义和类的使用两部分组成:在主程式中定义各对象并规定他们之间传替讯息的规律,程式中的一切操作都通过向对象传送讯息来实现;对象接到讯息后,启动讯息处理函式完成相应的操作。
面向对象程式设计(Object Oriented Programming,OOP)方法出现之前,程式设计师用面向过程的方法开发程式。面向过程的方法把密切相关、相互依赖的数据和对数据的操作相互分离这种实质上的依赖与形式上的分离使得大型程式不但难以编写,而且难以调试和修改。