课程主要内容
面向对象基本概念和原理
UML( UnifiedModeling Language )基础
面向对象设计原则
面向对象设计模式
什么是面向对象
面向对象的方法是一种分析方法、设计方法和思维方法。
面向对象方法学的出发点和所追求的基本目标是使人们分析、设计与实现一个系统的方法尽可能接近人们认识一个系统的方法。
使描述问题的问题空间和解决问题的方法空间在结构上尽可能一致
第1章 面向对象基本思想
对问题空间进行自然分割,以更接近人类思维的方式建立问题域模型,以便对客观实体进行结构模拟和行为模拟,从而使设计出的软件尽可能直接地描述现实世界。
构造出模块化的、可重用的、维护性好的软件,同时限制软件的复杂性和降低开发维护费用。
什么是面向对象
从程序设计方法的角度看,面向对象是一种新的程序设计范型(paradigm),其基本思想是使用对象、类、继承、封装、聚合、关联、消息、多态性等基本概念来进行程序设计。
自八十年代以来,面向对象方法已深入到计算机软件领域的几乎所有分支。它不仅是一些具体的软件开发技术与策略,而且是一整套关于如何看待软件系统与现实世界的关系,用什么观点来研究问题并进行问题求解,以及如何进行系统构造的软件方法学。从这个意义上讲:
面向对象方法是一种运用对象、类、继承、封装、聚合、关联、消息、多态性等概念来构造系统的软件开发方法。
基本思想
从现实世界中客观存在的事物出发来建立软件系统
强调直接以问题域(现实世界)中的事物为中心来思考问题、认识问题,并根据这些事物的本质特征,把它们抽象地表示为系统中的对象,作为系统的基本构成单位。这可以使系统直接映射问题域,保持问题域中事物及其相互关系的本来面貌。
充分运用人类日常的思维方法
强调运用人类在日常的逻辑思维中经常采用的思想方法与原则,例如抽象、分类、继承、聚合、封装、关联等等。这使得软件开发者能更有效地思考问题,并以其他人也能看得懂的方式把自己的认识表达出来。
Ø 主要特点:
Ø 从问题域中客观存在的事物出发来构造软件系统,用对象作为对这些事物的抽象表示,并作为系统的基本构成单位。(对象)
Ø 用对象的属性表示事物的静态特征;用对象的服务(操作)表示事物的动态特征。(属性与服务)
Ø 对象的属性与服务结合为一体,成为一个独立的、不可分的实体,对外屏蔽其内部细节。(封装)
Ø 对事物进行分类。把具有相同属性和相同服务的对象归为一类,类是这些对象的抽象描述,每个对象是它的类的一个实例。(分类)
Ø 通过在不同程度上运用抽象的原则可以得到较一般的类和较特殊的类。特殊类继承一般类的属性与服务,从而简化系统的构造过程及其文档。(继承)
Ø 复杂的对象可以用简单的对象作为其构成部分。(聚合)
Ø 通过关联表达对象之间的静态关系。(关联)
总结:
用类和对象作为系统的基本构成单位。对象对应问题域中的事物,其属性与服务刻画了事物的静态特征和动态特征,它们之间的继承关系、聚合关系、消息和关联如实地表达了问题域中事物之间实际存在的各种关系。
因此,无论系统的构成成分,还是通过这些成分之间的关系而体现的系统结构,都可直接地映射问题域。
UML
图形化的建模语言
开发者用来为面向对象系统建立模型
具有灵活性与可扩展性
UML结构型图:识别对象和类、描述对象和类之间的关系(静态结构)
UML行为型图:对象如何协作产生满足要求的系统行为(动态性质)
设计模式
面向对象思想的发展使得在软件开发中使用模式化的方法受到了重视,模式化的思想来源于建筑业。
建筑大师Alexander:每一个模式描述了一个在我们周围不断重复发生的问题以及该问题解决方案的核心,这样你就可以一次又一次的使用该方案而不必做重复劳动。
就像建筑业用预制的墙和窗来构筑房屋,在面向对象设计中我们使用对象和接口代替墙和窗来构筑系统,它们的核心都在于提供了相关问题的解决方案。
模式化的设计使系统更稳定、易修改、易扩展、易理解、易测试。
90年代末,被称为四人帮的GoF发表了在面向对象编程中使用模式化方法研究的开创性著作-《设计模式-可复用面向对象软件的基础》(《Design Patterns-Elements of Reusable Object-Oriented Software》)。
其中提出了23种模式,这23种模式又可以被划分为三类:
创建型:与对象创建有关
结构型:处理类或对象组合
行为型:对象或类怎样交互和怎样分配职责
第1章. 面向对象思想
一种观察世界的方式
现实世界问题例。(济南男孩A送花给北京女孩B)
How?
代理和团体
解决问题的方法是找到一个合适的代理C,并把要求告诉他。
代理有责任完成你的需求。
A没必要理解C使用什么方法来完成任务,这些细节通常是隐蔽的。
一个面向对象的程序是由一个相互作用的代理团体组成,这些代理被称作对象。
每一个对象承担一个角色。
每一个对象都提供一种服务或者执行一种动作,以便为团体中其他对象服务。
对象
对象是独立存在的客观事物,它由一组属性和一组操作构成。
属性和操作是对象的两大要素。属性是对象静态特征的描述,操作是对象动态特征的描述。
属性一般只能通过执行对象的操作来改变。
操作又称为方法或服务,它描述了对象执行的功能。通过消息传递,还可以为其它对象使用。
复合对象
划分(partition)
聚合(aggregation)
部分/整体
部分/整体关系中有两种方式:组合和聚合。
PC机是一个组合的例子,一个部分对象(CPU)只能属于一个唯一的整体对象(PC机)。
组合关系中部分和整体的关系很紧密。
聚合关系中则比较松散,一个部分对象可以属于几个整体对象。
消息和方法
送花例
团体的成员通过传达要求来相互合作。
在面向对象编程中,行为的启动是通过将“消息”传递给对此行为负责的代理(对象)来完成的。
消息对行为的要求进行编码,并且随着执行要求所需的附加信息(参数)来一起传递。
“接收器”就是消息发送的对象。如果接收器接受了消息,那么同时它也接受了消息所包含的行为责任。然后,接受器响应消息,执行相应的“方法”以实现要求。
消息传递与过程调用
每一条消息都有一个指定的接收器(对象)相对应;接收器就是消息发送的对象。过程调用没有指定的接收器。
消息的解释由接收器决定,并且随着接收器的不同而不同。
动态绑定。 (动态决定 消息的解释是由父类还是子类的方法)
信息隐藏
作为某对象提供的服务的一个用户,只需要知道对象将接受的消息的名字。
不需要知道怎么完成要求,需要执行哪些动作。
在接收到一条消息后,对象会负责将该项任务完成。
责任???
用责任来描述行为。A对行为的要求仅表明他所期望的结果,C可随意选择使用的方法来实现所期待的目标,并在此过程中不受A的干扰。
提高了抽象水平,对象更加独立。(A想要排序,调用排序方法。C可以使用各种排序函数)
不干预原则
允许对象以任何 它认为合适的 不干涉其他对象的方式来完成任务,而不要干预它。
类和实例
C是花商的一个特例。
C是花商(Florist)类(class)的一个实例(instance)
类
根据抽象的原则对客观事物进行归纳和划分,只关注与当前目标相关的特征,把具有相同特征的事物归为一个类。它是一个抽象的概念。
类是具有相同属性和相同操作(服务)的对象的集合。它包括属性和操作。
类和实例
所有对象都是类的实例。
在响应消息时调用何种方法由类的接收器(对象/实例)来决定。
一个特定类的所有对象使用相同的方法来响应类似的消息。
每一个对象都是某个类的实例。类是一组相似的对象 。
类是对象相关行为的储存库(repository)。即同一个类的所有对象都能执行同样的动作。、
类的层次
除了知道C是花商外,还知道他是商人、人类、哺乳动物、物质对象。
在每一层次上,都可以了解特定的信息,这些信息适用于所有较低层次。
付款适用其他店主。
继承
类被组织成有单个根节点的树状结构,称为继承层次结构。与类实例相关的数据和行为都会被树结构中的后代自动继承。
在类层次结构中与某层相联系的信息(数据、行为)都会自动地提供给该层次结构的较低层次中。
继承表达了对象的一般与特殊的关系。
特殊类的对象具有一般类的全部属性和服务。
类可以组织成一个有层次的继承机构。
一个子类继承层次树中更高一层的父类的属性。
抽象父类是指没有具体实例的类,他只是用来产生子类。
一般/特殊
对象之间存在着一般和特殊的结构关系,也就是说它们存在继承关系。很多时候也称作泛化和特化关系。
方法绑定与改写
鸭嘴兽?
处理一般规则外的特例?
改写
将子类中某一方法取与父类方法相同的名称,结合寻找方法的规则(当响应特定消息时)实现改写。
方法绑定与改写
接收器搜索并执行相应的方法以响应给定的消息。
如果没有找到匹配的方法,搜索就会传导到此类的父类。搜索会在父类链上一直进行下去,直到找到匹配的方法,或者父类链结束。
如果能在更高类层次找到相同名称的方法,所执行的方法就称为改写了继承的行为。
多态
多态性是指一般类中定义的属性和服务,在特殊类中不改变其名字,但通过各自不同的实现后,可以具有不同的数据类型或具有不同的行为。
如不同花商送花方式。
多态可通过重载和类等级不同层次共享同一方法名字等方式来实现。
JAVA中的重写/改写和重载
重写一般是指父类和子类之间,子类重写了父类的一个方法,当然方法名是一样的,而且不能改变父类方法的返回值,比如说父类是返回String,子类重写了这个方法,想返回一个int,那是不行的,也得返回String。
重载是一个类里面,写了多了同名的方法,各个方法的返回值类型可以不一样。区分重载方法可以通过参数列表的个数,类型和顺序。
第2章 抽象
抽象
抽象是指对于一个过程或者一件制品的某些细节有目的的隐藏,以便把其他方面、细节或者结构表达得更加清楚。(信息隐藏)
抽象,是控制复杂性时最重要的工具。
老虎、狮子(猛兽)
抽象实例:地图集
如果打开一本地图集,一般看到的常是一幅世界地图。该地图只显示了一些最主要的特征,如主要的山脉、海洋等等,但细节基本上都被忽略了。
随后的一系列地图将覆盖小一些的地理区域,也能处理更多的细节。例如,一块大陆(如各大洲)的地图将包括国家的边界和主要的国家。更小的区域(如国家)地图,将包括城市、各山峰的名称。一个城市的地图可能会包括进出该城市的主要道路,再小一些的地图甚至还会画出一些建筑物。
抽象技术
每个抽象层次,包括了某些信息,也忽略了某些信息。
人们通常使用一些简单的工具来建立、理解和管理复杂的系统。其中最重要的技术称为“抽象”(abstraction)。
抽象的层次
在典型的OOP程序中,有许多级抽象。
更高层次的抽象部分地体现了面向对象程序面向对象的特征。
确定正确的抽象级别
在软件开发的早期,关键的问题就是确定合适层次的抽象。
既不要忽略太多的细节,也不要包括太多的细节。
第3章 类和方法
封装
利用数据抽象进行编程。
数据类型两个方面:外部用户/实现者
避免重复的代码
保护类受到不必要的修改
概念
实例
实例变量/数据成员/数据字段
对象=状态(实例变量)+行为(方法)
对象外部看,客户只能看到对象的行为;对象内部看,方法通过修改对象的状态,以及和其他对象的相互作用,提供了适当的行为。
类的定义
可视性修饰符public,private
Java和C++中,封装性由程序员确定。
惯例
类名首字母大写。
数据字段private
Accessor(Getter)/Setter(访问器)
类中声明次序建议-可读性
先列出主要特征,次要的列在后面。
私有数据字段列在后面。
构造函数列在前面。
定义和实现分离?
Java,C#:方法主体直接放在类定义中。
C++:分离
接口
不提供实现
接口定义新类型,可以声明变量
类的实例可以赋值给接口类型变量
向前定义
多个互相引用的类(相互递归)
Java全文扫描、C++向前定义
Java 语言在生成代码之前会扫描整个文件,这样,如果程序文件的前面部分引用在文件后面声明的类,就不会产生任何冲突。其他的语言,例如 C++,会从前到后地依次处理程序文件中的类和方法去。名称在使用之前必须至少进行部分定义。
类的数据字段(类属性)
被一个类的所有实例共享的公共数据字段。
如何对该字段初始化?
每个实例都执行对公共数据字段的初始化?
没有实例执行初始化任务?
对象本身不对共享字段初始化。内存管理器自动将共享数据初始化为某特定值,每个实例去测试该特定值。第一个进行测试的做初始化。
Jav