《五章面向对象基本概念》由会员分享,可在线阅读,更多相关《五章面向对象基本概念(48页珍藏版)》请在金锄头文库上搜索。
1、第五章面向对象基本概念1提纲提纲5.1 什么是面向对象什么是面向对象?5.2 5.2 为什么要面向对象为什么要面向对象?5.3 5.3 面向对象基本概念面向对象基本概念5.4 5.4 面向对象软件工程面向对象软件工程5.5 5.5 面向对象基本原则面向对象基本原则25.1 5.1 什么是面向对象?什么是面向对象?人类认识世界的两个最基本的法则:分类:任何事物都有其所属的类别,认识事物时首先识别类;(抽象)组成:复杂事物都是由简单事物组成的。(聚集)面向对象基本思想:任何事物都是对象,客观世界是由各种互相联系的对象组成的;每个对象都有自己的内部状态和运动规律;不同对象之间相互作用构成了各种各样不
2、同的系统。35.2 5.2 为什么要面向对象?为什么要面向对象?1.面向对象技术采用主体-动作模式来刻画世界,符合人类认识世界的规律。对于面向对象的用户界面,总是先选定一个界面对象,如一段正文或者一个图标,然后在这个对象上进行操作;对于面向对象的程序设计语言,先指定接受消息的对象,然后才在对象上执行消息指定的操作;对于面向对象的分析和设计,也是先确定系统中的实体对象,然后再确定在这些对象上可能实施的操作。传统的面向过程的程序设计语言最关心的是过程,而过程实施的对象是作为过程参数传递的。面向对象中的数据是主动的,面向过程中的数据是被动的。人类认识客观世界时也是先主体后动作的。45.2 5.2 为
3、什么要面向对象?为什么要面向对象?2.程序设计方法学要求分析、设计和实现一个系统的方法尽可能地接近认识一个系统的方法。人类在认识和理解现实世界的过程中,普遍运用着三个构造法则:(1)区分对象及其属性,例如,区分一棵树和树的大小或空间位置关系。(2)区分整体对象及其组成部分,例如,区分一棵树和树枝。(3)不同对象类的形成及区分,例如,所有树的类和所有石头的类的形成和区分。55.2 为什么要面向对象?为什么要面向对象?构造程序常用的方法如下:功能分解法:功能分解=功能+子功能+功能界面功能分解需要经验功能及其子功能只是间接地反映问题的实质,即使分析员认为功能划分清楚了,仍然无法验证功能集合是否精确
4、完整地表达了问题需求。功能经常发生变化,功能的大小(粒度)如何选择?程序算法(为主)数据结构(为辅)wirth定律问题空间和解空间不一致65.2 为什么要面向对象?为什么要面向对象?数据流方法数据流方法数据流数据转移数据存储数据字典加工说明将世界映射为数据流和加工类似于事件及对事件的处理着眼于数据的变换(IPO),容易验证需求描述的准确性,不是简单的功能划分。分析的时候强调数据流,但是设计的时候强调功能,这样分析和设计之间必然进行转换。因此,问题空间和解空间仍然不一致。75.2 为什么要面向对象?为什么要面向对象?信息模型方法(实体关系图,语义数据模型)信息模型方法实体实体属性实体关系抽象实体
5、关联实体没有描述实体的服务没有描述实体之间发送消息的动态行为,只描述了静态的关联。扩展ER图才描述实体的分类和组成结构面向对象方法面向对象方法对象(属性及其服务)分类继承消息对象将属性和服务封装在一起直接从问题空间映射为解空间85.2 为什么要面向对象?为什么要面向对象?系统的易变性和稳定性功能数据流实体对象(过程抽象数据抽象)需求容易变;外部界面容易变;数据属性容易变;问题空间中的对象是稳定的。面向对象将系统变化限制在对象范围内,并加以控制,变化对系统的影响范围小。95.2 为什么要面向对象?为什么要面向对象?对象工程的wirth定律程序(算法)(数据结构)程序(算法数据结构)对象(算法数据
6、结构)程序对象对象对象面向对象并不排除功能划分,只不过功能划分的角度是站在外部使用者角度的,而且这些功能最终要分配到主体对象上。105.2 为什么要面向对象?为什么要面向对象?3.模块化要求(1)模块定义软件被划分成若干可单独命名和编址的部分,它们被称作模块,这些模块相互连接组成满足应用需求的软件系统。模块化是软件对付复杂问题所应具备的关键特性。(2)模块的特征模块的基本特征是抽象和实现信息隐藏。模块分模块界面和模块体两部分。模块对外的联系和相互作用只能通过模块接口进行。模块体是模块的具体实现细节,对外是不可见的。抽象和信息隐藏正是面向对象的主要特征。(3)模块化原则可分解性:降低系统的复杂程
7、度;模块应该具备一定的层次结构。可组合性:组合的模块中有些是可以复用的;模块必须具备较高的通用性和适用性,具备规范的接口,易于组装。可理解性:模块必须具有完整的语义特征,易于理解。面向对象正好满足模块化的要求。115.2 为什么要面向对象?为什么要面向对象?4.软件复用的支持对象技术使软件复用更臻完善和规范:对象封装和继承可以很好地支持软件复用。对象封装允许应用开发者将对象模块视作黑匣子,通过界面去理解和操作对象,而不去关心实现细节;(接口复用)对象继承容许对象实现复用具有相同特性的其它对象的代码,而不要去重复开发。(代码复用)基于对象的统一的语义模型,对象技术可提供统一的机制将对象模块组装在
8、一起,极大地复用已有的对象,满足各种应用需求。除了各种可复用的公共对象模块外,信息化社会的进步还要求人们开发满足各种应用需求的领域对象。(对象复用)125.2 为什么要面向对象?为什么要面向对象?5.软件维护要求软件维护需要对软件作部分的修改,这种修改应该是方便的,而且必须保证维护后软件的可靠性。这就对软件开发方法提出了较高的要求。软件开发过程不同阶段应该采纳相同的系统模型,使得不同阶段之间的信息不会因为转移而发生变形;如果发生变形,软件的追踪性就无法得到保证,软件的验证非常困难。面向对象的系统开发各阶段都是使用统一的建模方法。企业信息系统必须适应环境的经常性变化,应该根据企业内部的真实对象对
9、系统进行建模,这样当系统的功能发生变化时,只需要对真实对象的功能进行改变,而其接口可以不发生变化。135.3 5.3 面向对象基本概念面向对象基本概念对象(object)定义:对象是对问题域中某个实体的抽象(映射到计算机领域)。这里的实体既可以是物理实体,也可以是逻辑或者人为概念上的实体。对象是一个封装体,将对象的属性及其操作封装在一起。对象是一台自动机。对象属性集合表示对象的状态,对象的状态由对象的操作改变(当接收到其他对象发来的消息时)。并行性是对象的本质特征。(对象间的并行性、对象本身的并行性)145.3 5.3 面向对象基本概念面向对象基本概念类(class)定义:是对具有相同属性和行
10、为的一组对象的描述。在程序设计语言中,类是一种抽象数据类型。具体对象是类的实例。抽象类:用来定义协议。不具备直接的具体的对象实例。实例(instance)定义:按照类模板建立起来的具体对象就是实例;实例是一个具体的对象。(对象有泛指的含义)155.3 5.3 面向对象基本概念面向对象基本概念接口(interface)对象声明的每一个操作需要指定操作名、作为参数的对象和返回值类型,这就是所谓的操作的型构(signature)。对象操作所定义的所有对外提供服务的操作型构的集合被称为该对象的接口(interface)。对象接口描述了该对象所能接受的全部请求的集合,任何匹配对象接口中型构的请求都可以发
11、送给该对象。在面向对象系统中,接口是基本的组成部分。对象只有通过它们的接口才能与外部交流,如果不通过对象的接口就无法知道对象的任何事情,也无法请求对象做任何事情。对象接口与其功能实现是分离的,不同对象可以对请求做不同的实现,也就是说,两个有相同接口的对象可以有完全不同的实现。当给对象发送请求时,所引起的具体操作既与请求本身有关又与接受对象有关。支持相同请求的不同对象可能对请求激发的操作有不同的实现。发送给对象的请求和它的响应操作在运行时刻的连接就称之为动态绑定(dynamicbinding)。165.3 5.3 面向对象基本概念面向对象基本概念类型(type)类型是用来标识特定接口的一个名称。
12、一个对象可以有许多类型,并且不同的对象可以共享同一个类型。对象接口的某部分可以用某个类型来刻画,而其他部分则可用其他类型刻画。两个类型相同的对象只需要共享它们的部分接口。类类型和型和型和型和类类之之之之间间有什么关有什么关有什么关有什么关联联呢?呢?呢?呢?175.3 5.3 面向对象基本概念面向对象基本概念类型和类之间的关联类是对象的构造模板,类型是对象的操作型构集合。因此,类型规定了对象所能处理的消息集合。类是类型的基础,类型靠类来定义。185.3 5.3 面向对象基本概念面向对象基本概念抽象类(abstractclasss)所有的对象都是通过类来实例化的,但是反过来却不是这样。并不是所有
13、的类都是用来实例化对象的。如果一个类中没有包含足够的信息来实例化一个具体的对象,这样的类就是抽象类。抽象类往往用来表征对问题领域进行分析、设计得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。如:对圆、三角形进行抽象形成的图形概念。抽象类在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。只能通过派生类实例化对象。在面向对象领域,抽象类主要用来进行类型隐藏。可以构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。195.3 5.3 面向对象基本
14、概念面向对象基本概念抽象类和接口的区别:abstractclassDemoabstractvoidmethod1();abstractvoidmethod2();interfaceDemovoidmethod1();voidmethod2();1.抽象类可以有自己的数据成员,也可以有非abstract操作成员;接口的操作成员全部是abstract的,而且一般没有数据成员,即使有也只能是staticfinal的,不能修改。2.抽象类和接口都可以实现DBC(DesingByContract)的设计思想;3.接口是一种特殊的抽象类;4.抽象类定义了一种继承关系,接口定义了一种契约关系。5.Java中
15、,只能从一个抽象类派生子类(单继承),但是可以有多个类实现一个相同的接口。205.3 5.3 面向对象基本概念面向对象基本概念消息(message)对象之间相互作用构成系统,那么如何相互作用呢?通过发送消息。消息是发送对象为了激活接收对象执行某一个功能的唯一手段。消息接收对象的标识消息名参数方法(method):对象的操作成员属性(attribute):对象的数据成员215.3 5.3 面向对象基本概念面向对象基本概念继承(inheritance)继承是类实现可重用性(避免代码的重复)和可扩充性(同一个类可以扩充应用到不同的场合)的重要特征;一个类可以定义为另一个更一般类的特殊情形,一般类是特
16、殊类的父类,特殊类是一般类的子类;继承是is-a的关系,如:卡车是一个汽车,因此,子类的实例也是父类的实例。从实现的角度看:子类类型变量可以赋值给父类类型变量,反之不行。从这个角度来讲,一个变量就具备多种类型:静态类型(声明的时候)、动态类型(运行的时候)。225.3 5.3 面向对象基本概念面向对象基本概念子类可以覆盖(override)父类的操作,因此,子类可以接管父类对请求的处理。覆盖不能破坏父对象的语义,否则会破坏is-a关系。继承是一种白盒(white-box)复用,是在编译阶段确定的,因此破坏了封装性,直接的后果就是:父类的任何变化都对子类有影响。单继承和多继承235.3 5.3
17、面向对象基本概念面向对象基本概念多态性(polymorphism)多态性(多形):一个对象发送消息给另一个对象的时候不需要知道接受消息的对象具体所属的类。换句话说:一个消息可以和多个对象结合,而且这些对象属于不同的类。从实现的角度看:一个消息的处理方式在不同的类中可以有不同的实现方式。当对于一个接口有多种实现方式的时候就要用到多态性的概念。245.3 5.3 面向对象基本概念面向对象基本概念例:Figurefig;Rectanglerect;Circlecir;Triangletri;变量fig的静态类型是Figure、rect的静态类型是Rectangle、cir的静态类型是Circle、t
18、ri的静态类型是Triangle。按照继承的“isa”语义,子类对象也是父类对象,因此,figrect;figcir;figtri;都是合法的。255.3 5.3 面向对象基本概念面向对象基本概念当系统对象发送一个draw消息给fig对象时,fig会执行什么操作呢?fig会根据运行时刻所属的动态类型来决定执行那个类的draw操作(动态绑定dynamicbinding:在运行时刻可以替换对象)。因此系统对象只要调用fig.draw()就可以实现drawRectangle、Circle或者Triangle的操作。假定所有的图形元素存放在fig中,那么:for (i=0; figi; i+) fig
19、i.draw();而要在面向过程的程序设计方法中,则比较复杂:switch(typeof(fig)casetypeof(rect):rect.draw();break;casetypeof(cir):cir.draw();break;casetypeof(tri):tri.draw();break;如果要增加一个Ellipse类型呢?注意:fig的静态类型仍为Figure,但其动态类型增加了ellipse。265.3 5.3 面向对象基本概念面向对象基本概念多态性的重要意义:多个类型(从相同的父类型中衍生出来)可被当作同一种类型对待。用父类去代表多个子类,只让自己的代码与父类打交道。运用多态性
20、可以简化设计、使设计灵活,易于扩展。play()275.3 5.3 面向对象基本概念面向对象基本概念public class Music / Doesnt care about type, so new types/ added to the system still work right:static void tune(Instrument i) / .i.play();static void tuneAll(Instrument e) for(int i = 0; i e.length; i+)tune(ei);public static void main(String args) I
21、nstrument orchestra = new Instrument5;int i = 0;/ Upcasting during addition to the array:orchestrai+ = new Wind();orchestrai+ = new Percussion();orchestrai+ = new Stringed();orchestrai+ = new Brass();orchestrai+ = new Woodwind();tuneAll(orchestra); /285.3 5.3 面向对象基本概念面向对象基本概念在Java编程语言中,类的多态性通过方法的重载(
22、overloading)、覆盖(overriding)和接口来实现。方法重载方法重载方法重载是指多个方法具有相同的名称,但各个方法的参数表不同,即参数的类型和参数的数量不同。例如,求一个数的立方,其方法的名称为cube,它有整型、浮点型和双精度型三种不同类型的参数和返回值:intcube(inti);floatcube(floata);doublecube(doubled);调用这个方法时,系统根据实际参数的类型自动选择相应的方法。例如,cube(5),cube(3.2f),cube(6.7)表示调用三种不同类型的cube方法。覆盖覆盖类的方法不仅名称相同,参数也完全相同,但它们的功能不同,这
23、时子类中的方法覆盖了父类中同名的方法。接口接口接口实际上是一种特殊的类,其中只有方法的原型,即只给出方法的名称、参数和返回值的类型,没有方法体。这些方法的实现在其子类中具体定义。类的多态性使方法的调用更加容易、灵活和方便。295.4 面向对象软件工程面向对象软件工程软件生存期模型(面向对象软件开发模型)软件生存期的划分:系统分析、系统设计、对象设计、实现、维护等。开发模型:OO技术适用于任何开发模型有些模型(喷泉模型)支持OO技术比别的模型好OO技术适合原型化方法,新的开发模型基本上是采纳迭代增模开发方式。如:RUP的初始阶段(inceptionphase)、细化阶段(elabration)、
24、构造阶段(construction)、移交阶段(transition),迭代开发计划贯穿于所有阶段,每一次迭代对模型容量是一种增加。305.4 面向对象软件工程面向对象软件工程面向对象分析完成对问题空间的分析和建立系统模型。具体任务是确定和描述系统中的对象、对象的静态特性和动态特性、对象间的关系及对象的行为约束等。原则:(1)构造(对象组装)和分解(细化大粒度对象)相结合。(2)抽象化(强调实体的本质和内在属性,而忽视与问题无关的属性)和具体化(对抽象的实体进行扩充)相结合。(3)封装原则:接口和实现相分离(4)相关原则:静态关联(整体与部分)、动态关联(消息传递)(5)行为约束原则:必须反映
25、和保持对象的语义特征。内容:静态结构分析:确定对象及对象类、确定对象之间的关系(抽象、聚集和一般关联)动态行为分析:描述对象的合法状态转换序列。315.4 面向对象软件工程面向对象软件工程面向对象设计从计算机实现的角度确定系统的解决方案重用面向对象分析阶段的结果:因为和问题域空间的结构一致,不是面向任务的。内容:系统设计:软件体系结构设计、系统总体结构设计(考虑功能和性能两个方面)、系统数据存储设计、系统资源访问设计、网络与分布设计、并发性设计、对象互操作方式(过程驱动还是事件驱动)。对象设计:对系统分析阶段的对象及其关系进行扩充,如:扩充人机接口、资源访问、存储访问、过程控制方面的对象;对象
26、关系的优化等。325.4 面向对象软件工程面向对象软件工程面向对象程序设计原则:复用性、可扩充性、健壮性(不要过分强调技巧和优化)。基于面向对象技术开发的项目管理培训和人员:系统结构设计和项目管理员、模型建立者、接口建立者、组件建立者。选择和购买组件计划和安排效率和质量面向对象的开发方法几种经典的分析和设计方法:OMT(ObjectModelingTechnique)RumbaughBooch93BoochOOA/OOD/YourdonCoadRDD(ResponsibilityDrivenDesign)Wirfs-BrockOOSE(ObjectOrientedSoftwareEnginee
27、ring)/Jacobson335.5 5.5 面向对象基本原则面向对象基本原则1.单一职责原则SRP(SingleResponsibilityPrinciple):就一个类而言,应该仅有一个引起它变化的原因。(这个原因就是类的职责)在构造对象时,将对象的不同职责分离至两个或多个类中,确保引起该类变化的原因只有一个。提高内聚、降低耦合。在实际应用中,可以对经常使用或经常需要改动的模块应用该原则。345.5 5.5 面向对象基本原则面向对象基本原则2.开闭原则OCP(OpenClosedPrinciple):SOFTWAREENTITIES(CLASSES,MODULES,FUNCTIONS,E
28、TC.)SHOULDBEOPEN FOR EXTENSIONOPEN FOR EXTENSION,BUTCLOSED FOR CLOSED FOR MODIFICATIONMODIFICATION.对于扩展是开放的(Openforextension):模块的行为可以扩展。对于更改是封闭的(Closeformodification):对模块行为进行扩展时,不必改动客户端模块的源代码或者二进制代码。在进行面向对象设计时要尽量考虑接口封装机制、抽象机制和多态技术。该原则同样适合于非面向对象设计的方法,是软件工程设计方法的重要原则之一。OCP的关键是抽象,抽象的目的是创建一个固定却能够描述一组任意个可
29、能行为的基类。而这一组可能的行为则表现为派生类。对于基类的更改是封闭的,所以它里边的方法一旦确定就不能更改。模块通过抽象基类进行引用,对派生类的扩展并不影响整个模块,所以它是开放的。不对程序中对程序中对程序中对程序中频繁变化的部分做出抽象,拒绝不成熟的抽象。频繁变化的部分做出抽象,拒绝不成熟的抽象。频繁变化的部分做出抽象,拒绝不成熟的抽象。频繁变化的部分做出抽象,拒绝不成熟的抽象。355.5 5.5 面向对象基本原则面向对象基本原则365.5 5.5 面向对象基本原则面向对象基本原则375.5 5.5 面向对象基本原则面向对象基本原则符合OCP原则的程序只通过增加代码来变化而不是通过更改现有代
30、码来变化,因此这样的程序就不会引起象非开放封闭(open-closed)的程序那样的连锁反应的变化。对变化进行封装:一种可变性不应当散落在代码的很多角落里,而应当被封装到一个对象里。385.5 5.5 面向对象基本原则面向对象基本原则3.Liskov替换原则LSP(LiskovSubstitutionPrinciple):子类应当可以替换父类并出现在父类能够出现的任何地方。这个原则是Liskov于1987年提出的设计原则。它同样可以从BertrandMeyer的DBC(DesignbyContract)的概念推出。运用替换原则时,我们尽量把类B设计为抽象类或者接口,让类C继承类B(接口B)并实
31、现操作A和操作B,运行时,类C实例替换B,这样我们即可进行新类的扩展(继承类B或实现接口B),同时无须对类A进行修改。395.5 5.5 面向对象基本原则面向对象基本原则 原始定义原始定义原始定义原始定义:若对于每一个类型S的对象o1,都存在一个类型T的对象o2,使得在所有针对T编写的程序P中,用o1替换o2后,程序P的行为功能行为功能行为功能行为功能不变,则S是T的子类型。Liskov1987LSP原则清楚地指出:继承中is-a关系是就行为功能而言。行为功能(behavior)不是内在的、私有的,而是外在、公开的,是客户程序所依赖的。行为功能(behavior)才是软件所关注的问题!所有所有
32、所有所有派生类的行为功能必须和客户程序对其基类所期望的派生类的行为功能必须和客户程序对其基类所期望的派生类的行为功能必须和客户程序对其基类所期望的派生类的行为功能必须和客户程序对其基类所期望的保持一致。保持一致。保持一致。保持一致。仅当派生类能完全替换基类时,我们才能放心地重用那些使用基类的函数和修改派生类型。405.5 5.5 面向对象基本原则面向对象基本原则4.依赖倒置原则DIP(DependencyInversionPrinciple):A.高层模块不应该依赖于低层模块。二者都应该依赖于抽象。B.抽象不应该依赖于细节。细节应该依赖于抽象。针对接口编程:应当使用接口和抽象类进行变量的类型声
33、明、参量的类型声明,方法的返还类型声明,以及数据类型的转换等。415.5 5.5 面向对象基本原则面向对象基本原则为什么要这样呢?回想糟糕设计的后果:很难添加新功能和修改功能,因为通过修改和扩充功能会影响系统中过多的模块,甚至会导致另一个模块发生问题。(缺乏灵活性)很难在别的应用程序中重用这个模块,因为不能将它从现有的应用程序中独立的提取出来。(不可重用性)为什么会这样?因为存在耦合。零耦合:两个类没有耦合关系;具体耦合:两个具体的(可实例化的)类之间,经由一个类对另一个具体类的直接引用造成的耦合关系抽象耦合:一个具体类和一个抽象类(或接口)之间的耦合关系。425.5 5.5 面向对象基本原则
34、面向对象基本原则具体耦合抽象耦合1.从问题的具体细节中分离出抽象,以抽象方式对类进行耦合;2.如果都这么处理会导致过多的类,一般对于易变化的类如此处理。435.5 5.5 面向对象基本原则面向对象基本原则5.接口隔离原则ISP(InterfaceSegregationPrinciple):不要强迫客户依赖于它们不用的方法。一个类对另外一个类的依赖性应当是建立在最小的接口上的。如果客户端只需要某一些方法的话,那么就应当向客户端仅提供这些需要的方法。提供接口意味着向客户端作出承诺,过多的承诺会给系统的维护造成不必要的负担。使用多个专门的接口比使用单一的接口要好。445.5 5.5 面向对象基本原则
35、面向对象基本原则6.合成/聚合复用原则(Composite/AggregationReusePrinciple,CARP):在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委托委托委托委托达到复用这些对象的目的。继承复用(白盒复用)(white-box)优点:实现容易;派生类也容易添加到系统中;缺点:破坏封装;超类不容易变化;静态实现。合成/聚合复用(黑盒复用)(black-box)优点:支持封装;动态实现。缺点:不易扩展;较多的对象管理负担。455.5 5.5 面向对象基本原则面向对象基本原则465.5 5.5 面向对象基本原则面向对象基本原则7.迪米特法则(LawofDemeter,LoD):最少知识原则:一个对象应当对其它对象有尽可能少的了解。只与你直接的朋友们通信,不要跟“陌生人”说话。朋友的条件条件条件条件:当前对象本身(this);以参量形式传入到当前对象方法中的对象;当前对象的实例变量直接引用的对象当前对象的实例变量如果是一个聚集,那么聚集中的元素也都是朋友;当前对象所创建的对象。475.5 5.5 面向对象基本原则面向对象基本原则遵循这些原则的目的就是:扩展性:容易添加新功能灵活性:代码修改平稳发生可插入性:能够容易地将一个类替换具有相同接口的另外一个类。48