各位山大的小伙伴们是不是对即将到来的面向对象考试搞得很烦躁呀~
是不是对老师发的只有关键词的提纲一脸懵逼呀~
本提纲是根据那份只有关键词的提纲整理的复习提纲。
提纲中知识点均来自老师的PPT,请放心使用。
如有问题请指正哈。
面向对象综述
类:
类是具有相同属性和相同操作(服务)的对象的集合。它包括属性和操作。
每一个对象都是某个类的实例。类是一组相似的对象 。
类是对象相关行为的储存库(repository)。即同一个类的所有对象都能执行同样的动作。对象:
对象是独立存在的客观事物,它由一组属性和一组操作构成。
属性和操作是对象的两大要素。属性是对象静态特征的描述,操作是对象动态特征的描述。方法:
方法又称为操作或服务,它描述了对象执行的功能。通过消息传递,还可以为其它对象使用。消息:
在面向对象编程中,行为的启动是通过将“消息”传递给对此行为负责的对象来完成的。
消息对行为的要求进行编码,并且随着执行要求所需的附加信息(参数)来一起传递。
“接收器”就是接收消息的对象。
消息的解释由接收器决定,并且随着接收器的不同而不同。继承:
在类层次结构中与某层相联系的信息(数据、行为)都会自动地提供地该层次结构的较低层次中。
特殊类的对象具有一般类的全部属性和服务。
一个子类继承层次树中更高一层的父类的属性。
抽象父类是指没有具体实例的类,他只是用来产生子类。封装:
把类密封成一个整体,只预留一定的接口供人使用
避免重复的代码
保护类受到不必要的修改信息隐藏:
作为某对象提供的服务的一个用户,只需要知道对象将接受的消息的名字。
不需要知道要完成要求,需要执行哪些操作。
在接收到一条消息后,对象会负责将该项任务完成。对象性质:
封装性:信息隐藏
自治性:主动数据
通信性:并发
暂存性:作用域/期
永久性:文档串行化多态
多态性是指一般类中定义的属性和服务,在特殊类中不改变其名字,但通过各自不同的实现后,
可以具有不同的数据类型或具有不同的行为
抽象抽象
抽象是指对于一个过程或者一件制品的某些细节有目的的隐藏,以便把其他方面、
细节或者结构表达得更加清楚。
抽象,是控制复杂性时最重要的工具。抽象层次
第一层次——团体:
在最高级别上,程序被视为一个对象的“团体”,这些对象间相互作用,以完成共同的目标。
第二层次——单元:
许多语言允许协同工作的对象组合到一个“单元”(unit)中。
例如,Java的“包” (packages),C++的“名字空间”(name spaces)。
这些单元允许某些特定的名称暴露在单元以外,而其他特征则隐藏在单元中。
第三层次——接口:
定义行为,但不描述如何来实现。
第四层次——服务实现方式:
考虑抽象行为的具体实现方式。
第五层次——具体实现:
关注执行一个方法的具体操作实现。抽象形式
分治法:
常用的一种抽象形式是将一层划分为多个组成部分。
例如,汽车是由发动机、传动机构、车身和车轮组成的。
从设计整车,到依次设计其组成部件、其接口,部件内部实现细节先不考虑。
特化分层:
有时这也称为分类法(taxonomy).
例如,生物分为动物和植物,动物又分为脊椎动物和无脊椎动物,脊椎动物包括哺乳动物,
哺乳动物又分为猫、狗……,等等
不同视角:
另一种形式的抽象,是对同一件物品提供不同的视角。
每一个视角会强调某一些细节而忽略其他细节,因此,对同一对象描述出不同的特性。
例如,机械师眼里的汽车和外行眼里的汽车,看法是很不一样的。
分类:
当系统中组件数量变大时,常用分类(Catalogs)来进行组织。
日常生活中常用到不同类型的分类。例如电话号码簿、Internet搜索引擎等。(京东目录)
相似地,软件中也有很多分类。例如,类的列表、类中定义的方法的列表等。
组合:
组合,是另一个由简单部分构建复杂结构的有力技术。
其中心思想,是由少量简单的形式,根据一些组合规则,构建出新的形式。
组合中的关键之处,在于既可对初始形式进行组合,也可以对新形式进行组合。
模式:
在我们遇到新问题时,大多数人都会查看已经解决过的老问题中,是否有与新问题相似的情况。
以前的问题可以作为一个解决问题的模型,略做修改可能就能解决新问题了。
这就是软件模式(pattern)的思想。
广泛应用于对象团体中成员之间的相互作用方式。
类
静态属性
多个对象都可以对静态属性进行操作,
实现同类多个对象间的数据共享。静态方法
静态方法为类所有,可以通过对象来使用,也可以通过类来使用。
但一般提倡通过类名来使用,因为静态方法只要定义了类,不必建立类的实例就可使用。
静态方法只能调用静态变量。
无this
构造和析构函数不能为静态成员。元类
元类是描述类的类
类也是对象,每个类一定是某个元类的实例
元类的实例化的结果为我们用class定义的类,正如类的实例为对象
元类对象中存储的是关于类的信息(类的版本,名字,类方法等)。反射和内省
反射和内省是指程序在运行过程中“了解”自身的能力。
反射工具都开始于一个对象,该对象是关于一个类的动态(运行时)体现。
比如java中的getSuperClass()方法。
反射的作用:程序中的错误定位方法以及灵活调用对象的方法如果两个或更多的方法具有相同的名称和相同的参数数目,java编译器如何匹配?
按照参数类型匹配,按照调用此方法的对象进行匹配。
继承
子类型
指符合替换原则的子类关系。
区别于一般的可能不符合替换原则的子类关系
替换原则:指如果类B是类A的子类,那么在任何情况下都可以用类B来替换类A,而外界毫无察觉。多重继承
一个对象可以有两个或更多不同的父类,并可以继承每个父类的数据和行为。继承的形式:
特殊化继承——
很多情况下,都是为了特殊化才使用继承。
在这种形式下,新类是基类的一种特定类型,它能满足基类的所有规范。
用这种方式创建的总是子类型,并明显符合可替换性原则。
与规范化继承一起,这两种方式构成了继承最理想的方式,也是一个好的设计所应追求的目标。
Window-TextWindow
规范化继承——
规范化继承用于保证派生类和基类具有某个共同的接口,即所有的派生类实现了具有相同方法界面的方法。
基类中既有已实现的方法,也有只定义了方法接口、留待派生类去实现的方法。派生类只是实现了那些定义在基类却又没有实现的方法。
派生类并没有重新定义已有的类型,而是去实现一个未完成的抽象规范。
也就是说,基类定义了某些操作,但并没有去实现它。只有派生类才能实现这些操作。
在这种情况下,基类有时也被称为抽象规范类。
构造继承——
一个类可以从其基类中继承几乎所有需要的功能,只是改变一些用作类接口的方法名,或是修改方法中的参数列表。
即使新类和基类之间并不存在抽象概念上的相关性。
树-独木舟
堆栈-队列
写二进制文件-写学生信息文件
构造子类化——
当继承的目的只是用于代码复用时,新创建的子类通常都不是子类型。这称为构造子类化。
一般为了继承而继承,如利用一些工具类已有的方法。
泛化子类化——
派生类扩展基类的行为,形成一种更泛化的抽象。
Window-ColoredWindow
扩展继承——
如果派生类只是往基类中添加新行为,并不修改从基类继承来的任何属性,即是扩展继承。(泛化子类化对基类已存在的功能进行修改或扩展,扩展子类化则是增加新功能)
由于基类的功能仍然可以使用,而且并没有被修改,因此扩展继承并不违反可替换性原则,用这种方式构建的派生类还是派生类型。
限制继承——
如果派生类的行为比基类的少或是更严格时,就是限制继承。
常常出现于基类不应该、也不能被修改时。
限制继承可描述成这么一种技术:它先接收那些继承来的方法,然后使它们无效。
双向队列-〉堆栈。
变体子类化——
两个或多个类需要实现类似的功能,但他们的抽象概念之间似乎并不存在层次关系,如控制机械鼠标和控制轨迹球。我们通常使用的更好的方法是将两个类的公共代码提炼成一个抽象类,比如PointingDevice,并且让这两个类都继承于这个抽象类。
结合子类化——
可以通过合并两个或者更多的抽象特性来形成新的抽象。
一个类可以继承自多个基类的能力被称为多重继承 。
如,助教类。
静态行为与动态行为
反多态(向下造型)
做出数值是否属于指定类的决定之后,通常下一步就是将这一数值的类型由父类转换为子类。
这一过程称为向下造型,或者反多态,因为这一操作所产生的效果恰好与多态赋值的效果相反。
例子: 通过一个多态的指针访问普通成员函数时访问的是子类的函数,
通过子类的指针访问虚函数时访问的是父类的函数。
(例子地址:https://blog.csdn.net/zzhongcy/article/details/38304545)静态方法绑定和动态方法绑定
静态方法绑定:编译器在编译期间就能完成绑定的叫做静态绑定。
动态方法绑定:响应消息时对哪个方法进行绑定是由接收器当前所包含的动态数值来决定的。
替换的本质
内存布局:
求得从特定的类实例化对象是需要多少存储空间?
求得引入派生类包含基类所不包含的数据需要多少储存空间?最小静态空间分配:
C++使用最小静态空间分配策略。运行高效。
只分配基类所需的存储空间。最大静态空间分配:
无论基类还是派生类,都分配可用于所有合法的数值的最大的存储空间。动态内存分配:
只分配用于保存一个指针所需的存储空间。在运行时通过对指针指向的数据来分配存储空间。复制:
浅复制(shallow copy):共享实例变量。
深复制(deep copy):建立实例变量的新的副本。实现方法:C++:拷贝构造函数,Java:改写clone方法克隆:
一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。这种过程便是克隆。
多态与软件复用
多态:
“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。多态的形式(重要):
改写(包含多态,overriding):层次关系中,相同类型签名,是重载的一种特殊情况,但是只发生在有父类和子类关系的上下文中。
重载(专用多态,overloading):类型签名区分。
多态变量(赋值多态):声明与包含不同。
泛型(模板):创建通用工具。重定义(总和重载和多态一起考):
当子类定义了一个与父类具有相同名称但类型签名不同的方法时。软件复用形式:
继承和组合(提供了一种利用已存在的软件组件来创建新的应用程序的方法)
重载- 签名与范畴:
签名:函数类型签名是关于函数参数类型、参数顺序和返回值类型的描述。
范畴:范畴定义了能够使名称有效使用的一段程序,或者能够使名称有效使用的方式。
例如:局部变量,public成员。
改写
代替与改进:
代替(replacement):在程序执行时,实现代替的方法完全覆盖父类的方法。
即,当操作子类实例时,父类的代码完全不会执行。
改进(refinement):实现改进的方法将继承自父类的方法的执行作为其行为的一部分。
这样父类的行为得以保留且扩充。协方差与反协方差:
很少有改变类型签名的需求,通常将类型在其继承层次上提升或降低。
当一个类型降低类型层次作为子类时,将使用协方差变化术语。
反之,当一个类型由子类化反向提升类型层次时,将使用反协方差变化术语。非方差
大多数语言都通过使用一种称为非方差的技术来避免协方差与反协方差问题。
即,子类不允许以任何方式改变关于改写方法的类型签名。
多态变量
多态变量:
多态变量是指可以引用多种对象类型的变量。
这种变量在程序执行过程可以包含不同类型的数值。
对于动态类型语言,所有的变量都可能是多态的。
对于静态类型语言,多态变量是替换原则的体现,如:Parent variable=new Child()多态变量的形式:
简单变量:
最简单的能够引用多种对象类型的变量。
接收器变量:
多态变量最常用的场合是作为一个数值,用来表示正在执行的方法内部的接收器。
如this,self等伪变量。
反多态(上面已经有定义了)
纯多态(多态方法)
支持可变参数的函数。
支持代码只编写一次、高级别的抽象
以及针对各种情况所需的代码裁剪。
通常是通过给方法的接收器发送延迟消息来实现这种代码裁剪的。向下造型:
向下造型是处理多态变量的过程。
框架
对于一类相似问题的骨架解决方案。
通过类的集合形成,类之间紧密结合,共同实现对问题的可复用解决方案
继承和改写的强大能力体现
对象互联
耦合和内聚
耦合描述类之间的关系,内聚描述类内部的关系。耦合种类:
内部数据耦合:内部数据耦合发生在当一个类的实例直接修改另外一个类中的本地数据值
(实例变量)时。
全局数据耦合:全局数据耦合发生在两个或者更多个类型都依赖于公用的全局数据结构而
绑定到一起的时候
控制(或顺序)耦合:一个类必须以一种由任何位置控制的特定的顺序来执行操作。
组件耦合:组件耦合发生在一个类包含的数据字段或数值为另外一个类的实例时。
参数耦合:参数耦合发生在一个类必须调用另外一个类的服务和例程时,此时两个
类之间所发生的唯一关系就是一个类需要为另一个类提供参数数目、类型和返回值类型。
子类耦合:子类耦合是面向对象编程所特有的,描述了一个类与其父类之间的关系。内聚种类:
随机内聚:对程序随意划分
逻辑内聚:算术函数库
时间内聚:如实现程序初始化的类
通信内聚:数据或者设备的manager
顺序内聚:避免顺序耦合
功能内聚:类中元素通过执行特定功能关联起来
数据内聚:数据结构
设计模式(这部分还是看书或者PPT吧233)
简单工厂:
简单工厂模式是有一个工厂类根据传入的参量决定创建出哪一种产品类的实例。工厂方法:
工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。
工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,
工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。抽象工厂:
抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,
创建多个产品族中的产品对象。这就是抽象工厂模式的用意。单例:
单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。适配器:
将一个类的接口转换成客户希望的另外一个接口。
Adapter模式使得原本由于接口不兼容而不能一起的那些类可以一起工作。
Adapter模式也叫做包装器Wrapper。代理:
为其他对象提供一种代理以控制对这个对象的访问。BRIDGE(桥接):
把抽象部分和行为部分分离,使它们都能独立变化。DECORATOR(装饰):
动态地给一个对象添加一些额外的职责
Decorator必须和要包装的的对象具有相同的接口
有时我们希望给某个对象而不是整个类添加一些功能。CHAIN OF RESPONSIBILITY (职责链):
在责任链模式里,很多的对象由每一个对象对其下家的引用而联接起来形成一条链。
请求在这个链上传递,直到链上的某一个对象决定处理此请求。
发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,
这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。
责任链可能是一条直线、一个环链甚至一个树结构的一部分。OBSERVER(观察者):
定义对象间的一种一对多的依赖关系,
当一个对象的状态发生改变时,所有依赖于他的对象都得到通知并被自动更新。STRATEGY(策略):
定义一系列算法,把他们一个个封装起来,并且使他们可以相互替换。
使算法可独立于使用它的客户。