《程序设计方法学第六章面向对象程序设计方法学概述.ppt》由会员分享,可在线阅读,更多相关《程序设计方法学第六章面向对象程序设计方法学概述.ppt(57页珍藏版)》请在第壹文秘上搜索。
1、第六章 面向对象程序设计方法学概述面向对象程序设计方法学主要内容n1.面向对象程序设计方法的基本概念n2.面向对象程序设计方法的起源n3. 面向对象计算的基本原理n4. 面向对象程序设计的基本原则n5. 面向对象分析与设计方法 基本概念 封装(encapsulation) 信息/实现的隐藏(information/implementation hiding) 对象标识(object identity) 消息(message) 类(class) 继承(inheritance) 多态性(polymorphism) 接口(interface)基本概念 封装,将属性和操作包装成一个单元,使得对状态的访
2、问和修改只能通过封装提供的接口进行。 信息/实现的隐藏,将某些属性或方法限制在封装内部使用,限制外部的可见性。 对象标识,每个对象可以作为软件实体被标识和处理,每个对象都有一个对象标识符(object identifier OID)。 消息,对象间发送请求的载体。 接口,一组没有公共代码的对象共享实现。基本概念 类,类是对象的类型(模版),对象是类的实例。 继承,子类隐式使用超类(或父类)的属性和操作。 多态性,子类覆盖(overriding)父类的方法,它和重载(overloading)的区别在于重载是在同一对象层次中,利用参数的不同来进行动态绑定(dynamic binding)。面向对象
3、程序设计方法的起源 1.符号抽象符号抽象 Backus1957 的Fortran实现使用了人们习惯的符号记法,而且确保了编译后的运行效率。 2.过程抽象过程抽象 C语言的发展使得函数概念的普及和大规模应用。一些相对完整的功能代码被封装在一个函数里面实现 3.信息隐藏和抽象数据类型信息隐藏和抽象数据类型 Wirth1980的Modula-2语言实现了模块,在不降低运行效率的情况下实现了信息隐藏和抽象数据类型 4.类型抽象类型抽象 挪威计算中心的Kristen Nygaard和Ole-Johan Dahl开发了Simula67语言; 70年代中期,Xerox Palo Alto研究中心开发了Sma
4、lltalk语言;这些语言用类、对象、重载、动态绑定技术实现了抽象数据类型,但是其运行效率不能让人满意,其抽象类型概念也不能让人接收让人接受,直到C和C+例子(c语言)过程抽象stack.h/*declarationoftheinterfaceofmodulestackofcharater*/ charpop(); voidpush(char); conststack_size=100;stack.cpp #includestack.h staticcharvstack_size; staticchar*p=v; charpop() /Checkforunderflowandpop voidp
5、ush(charc) /checkforoverflowandpush 进步:记法方便了程序设计 函数理清了算法之间的关系缺点:过渡依赖全局数据 语言本身缺乏模块化的支持例子(Modula-2)信息隐藏 define module stackexport qualified pop push;procedure pop(c:char);procedure push(c:char);end stackimplementation module stackfrom inout import writestringconst max = 50;typeindex=0.max;stk : array
6、index of chartop : index;procedure push(c:char);beginend push;begintop:=0;end stack.nmodule usestacknfrom inout import write,writelnnfrom stack import push,pop;nvarnletter : char;nbeginnpush(“A”);push(“B”); push(“C”); push(“D”);nwhile NOT empty() donPop(letter);nwrite(letter);nend;nend usestack.进步:引
7、入模块化概念,支持信息隐藏缺点:内建类型支持不好, 缺乏类型抽象例子(c+)类型抽象class stackPublic:virtual push(char var)=0;virtual char pop()=0; class stack_array : public stackpush(char var);编程的风格变为: 1.决定需要那些类 2.为每一个类提供完整的接口 3.为类、接口获得一般性(泛化) 4.实现接口的算法改进:内建类型支持好不足:缺乏对类型的类型 描述能力例子(c+)类型泛化template template class stackclass stackpublic:pub
8、lic:virtual void push(T& var)=0;virtual void push(T& var)=0;virtual T pop()=0;virtual T pop()=0;template template class stack_array : public stackclass stack_array : public stackpublic:public:void push(T& var);void push(T& var);T pop();T pop();改进:具有描述类型的 类型的能力缺点:只在设计时刻存 在一定程度的类型 泛化能力例子(JAVA)类型反射publ
9、ic class StackCount static String names = “array”,” list”; public static void main(String args) Class stackTypes = Class.forName( stack_array ), Class.forName(“stack_list”) ;stackTypes0.newInstance().push(typenames0);stackTypes0.newInstance().push(typenames1)改进:类型不仅存在于设计时刻,而且在运行时刻能够动态的确定类 型。运行时刻的类型支
10、持缩小了问题领域和机器领域的距离, 使得对问题的抽象更加方便的实现面向对象的抽象原理1.数据抽象原理 数据抽象提供了面向对象方法的始点,其核心就是实现了模块化与信息隐藏,同时它也是面向对象方法学的基础。 2.行为共享原理 行为共享是指许多实体具有相同的接口,将不同实体的相同操作定义为抽象的操作将给用户带来方便。3.进化原理 进化包括两种含义: 一是指系统随需求变化而修改和增加的情况; 二是指对复杂问题的增量式的求解过程。进化建议面向对象对修改封 闭,对增加开放 4.正确性原理 正确性的问题主要是由行为共享所导致的,当一个实体请求另外一个实体的某种行为时候,系统必须确保能够在共享的行为组中找到正
11、确的行为实现并运行它 面向对象计算模型是指对上述面向对象抽象原理的具体实现技术,大部分面向对象语言使用如下三类技术 1.封装 封装实现了数据抽象技术 2.分类 分类是实现行为共享的基础 A 集合 B 抽象数据类型 C 类 3.共享 共享技术用于实现行为共享和进化原理。在面向对象语言系统中,共享又统称为多态性。多态性表明一个对象可以属于多于一个的分类,这样,就有可能让两个不同的分类共享相同的行为。 多态性通用的特定的参数化多态包含多态重载强制多态多态性 强制多态预先规定了语言中各种类型之间的映射关系,是一种隐式做类型转换的方法。例如:2.0 + 2.0、2.0 + 2、2.0 + 2 重载允许一
12、个函数名使用多次,每次带有不同的参数,例如print(PrintWriter)和print(FileWriter),同样的命名使得程序容易设计和理解。 强制和重载合起来被称为特定的多态性,因为两者都用于特定的目的,还有两种多态用于比特定多态更加基础的形式。 参数化多态性,是为不同类型的参数提供相同的操作。假设一个队列需要同时支持两种类型,整型和字符型。在单态的系统中,需要建立两个类型来实现,这两个类型绝大多数代码类似或者相同;如果使用参数化多态,则可以指定队列参数的某种性质,而不是特定的类型,从而通过建立一个队列实现上述功能。通过模板概念实现参数化多态。 包含多态性是一种强调分类之间关系的程序
13、设计风格,一种分类可以替代一种分类,分类之间不在孤立,分类之间体现了继承关系 。通常期望面向对象的语言应该具有包含多态性的特征,因为它是一种很好的实现自底向上的设计工具。然而。另外一种观点则认为目前对继承关系的滥用破坏了面向对象思想的优秀性,应该在面向对象程序中放弃继承,通过其它的方式实现行为共享原理。矛盾的焦点在于如何建立分类之间的关系。 多态性一些面向对象的设计原则1.开闭原则(OCP)2.里氏代换原则(LSP)3.依赖倒转原则(DIP)4.接口隔离原则(ISP)5.合成聚合复用原则(CARP)6.迪米特法则(LoD)7.单责任原则(SRP)开闭原则(OCP) 开闭原则是面向对象程序设计的
14、第一原则,这个原则最早由Bertrand Meyer提出:“Software entities should be open for extension,but closed for modification”,即一个软件实体应该对扩展开放,对修改关闭。也就是说,当一个软件需要增加或者修改某些功能时候,应该尽可能的只是在原来的实体中增加代码,而不是修改代码。开闭原则保证了系统具有一定的稳定性,同时保证了系统的灵活性。开闭原则的另外一个叫法称为“对可变性的封装原则”。 若财务部颁布主板和内存应使用额外费用,则需修改如下: 开闭原则(OCP)计算部件数组中各个部件价格的总和。 开闭原则(OCP)较
15、好的一种设计方式是:将计价策略合并到Part的getPrice()方法中。Part和ConcretePart类的示例如下: 里氏代换原则(LSP) 里氏代换原则最早由Barbara Liskov提出:“基类出现的地方,子类一定可以出现”,也就是对基类是合法的操作,对子类也一定合法。正方形是否是长方形的子类? 里氏代换原则(LSP)长方形类长方形类publicclassRectanglelongwidth;longheight;publicvoidsetWidth(longwidth)this.width=width;publiclonggetWidth()returnwidth;publicv
16、oidsetHeight(longheight)this.height=height;publiclonggetHeight()returnheight;正方形类正方形类publicclassSquareextendsRectanglepublicvoidsetWidth(longwidth)this.width=width;this.height=width;publiclonggetWidth()returnwidth;publicvoidsetHeight(longheight)this.width=height;this.height=height;publiclonggetHeight()returnheight;一个Rectangle对象的合法操作,对Square却非法!public void resize(Rectangle r)while(r.getHeight()结构领域商业领域应用领域确定类的领域 应用领域类 文件集合类(SetFile) 商业领域类 文件类(File) 文件流类(FileStreamOpt) 文件合并分割类(FileCutMerge) 结构领域类