7.1 面向对象基础
7.1.1 面向对象的基本概念
面向对象 = 对象 + 分类 + 继承 + 通过消息的通信
7.1.1.1 对象
在面向对象的系统中,对象是基本的运行时的实体,它既包括数据(属性、状态),也包括作用于数据的操作(行为、方法、函数)。
在对象内的操作通常称为方法。一个对象通常可由对象名、属性和方法三个部分组成。
构造对象的方法:
类名 对象名 = new 类名();
调用成员属性/方法:
对象名.成员属性(方法);
7.1.1.2 消息
对象之间进行通信的一种构造叫作消息。当一个消息发送给某个对象时,包含要求接收对象去执行某些活动的信息。接收到信息的对象经过解释,然后予以响应。这种通信机制称为消息传递。
7.1.1.3 类
一个类定义了一组大体上相似的对象。一个类所包含的方法和数据描述一组对象的共同行为和属性。
类是在对象之上的抽象,对象是类的具体化,是类的实例(Imstance)。
类可以分为三种:实体类、接口类(边界类)和控制类
-
实体类
实体类的对象表示现实世界中真实的实体,如人、物等。
是应用领域中的核心类,一般用于保存系统中的信息以及提供针对这些信息的相关处理行为。
-
接口类(边界类)
接口类(边界类)的对象为用户提供一种与系统合作交互的方式,分为人和系统两大类。
系统内对象和系统外参与者的联系媒介。
-
控制类
控制类的对象用来控制活动流,充当协调者。主要是协调两种类对象之间的交互。
有些类之间存在一般和特殊关系,即一些类是某个类的特殊情况,某个类是一些类的一般情况。这是一种 is-a关系,即特殊类是一种一般类。特殊类是一般类的子类,一般类是特殊类的父类。
7.1.1.4 方法重载
一个类可以具有多个同名而参数类型列表不同的方法,被称为方法重载。
重载的不同类型:
- 方法名相同 参数个数不同
- 参数类型不同
- 参数类型顺序不同
7.1.2 面向对象三大特征
7.1.2.1 封装
封装是一种信息隐蔽技术,它的目的是使对象的使用者和生产者分离,使对象的定义和实现分开。
进行封装时,常将函数声明为 private 类型,是为了**实现数据隐藏,以免意外更改 **。
对象是封装数据和行为的整体。
7.1.2.2 继承
继承是父类(超类、基类)和子类(派生类)之间共享数据和方法的机制
一个父类可以有多个子类,这些子类都是父类的特例,父类描述了这些子类的公共属性和方法。
一个子类可以继承它的父类(或祖先类)中的属性和方法,这些属性和操作在子类中不必定义,子类中还可以定义自己的属性和方法。
只从一个父类得到继承,叫作单重继承。如果一个子类有两个或更多个父类,则称为多重继承。
7.1.2.3 多态
在收到消息时,对象要予以响应。不同的对象收到同一消息可以产生完全不同的结果,这一现象称为多态
多态的实现受到继承的支持,利用类的继承的层次关系,把具有通用功能的消息存放在高层次,而不同的实现这一功能的行为放在较低层次,在这些低层次上生成的对象能够给通用消息以不同的响应。
编译看等号左边,运行看等号右边
Person person = new Student();
//编译期间看左边的类中有无该方法/属性,而实际在运行时执行的是右边类中的方法/属性
附加:动态绑定
绑定是一个把过程调用和响应调用所需要执行的代码加以结合的过程。
在一般的程序设计语言中,绑定是在编译时进行的,叫作静态绑定。动态绑定则是在运行时进行的。
多态有不同的形式,Cardelli 和 Wegner 把它分为 4类:
参数多态和包含多态称为通用的多态,过载多态和强制多态称为特定的多态
参数多态是应用比较广泛的多态,被称为最纯的多态。
包含多态在许多语言中都存在,最常见的例子就是子类型化,即一个类型是另一个类型的子类型。
过载多态是同个名字在不同的上下文中所代表的含义不同
7.1.3面向对象设计原则(记背)
-
单一责任原则
就一个类而言,应该仅有一个即引起它变化的原因。当需要修改某个类的时候原因有且只有一个,让一个类只做一种类型责任
-
开放-封闭原则
软件实体(类、模块、函数等)应该是可以扩展的,即开放的;但是不可修改的,即封闭的。
-
里氏替换原则(基类出现,子类一定可以出现)
子类型必须能够替换掉他们的父类(基类)型。即,在任何父类可以出现的地方,都可以用子类的实例来赋值给父类型的引用。
-
依赖倒置原则(依赖于抽象,而不依赖于细节(实现))
抽象不应该依赖于细节,细节应该依赖于抽象。即,高层模块不应该依赖于低层模块,二者都应该依赖于抽象
-
接口分离原则(依赖于抽象,不要依赖于具体)
不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。
-
重用发布等价原则
重用的粒度就是发布的粒度。
-
共同封闭原则
包中的所有类对于同一类性质的变化应该是共同封闭的。一个变化若对一个包产生影响,则将对该包中的所有类产生影响,而对于其他的包不造成任何影响。
-
共同重用原则
一个包中的所有类应该是共同重用的。如果重用了包中的一个类,那么就要重用包中的所有类。
-
无环依赖原则
在包的依赖关系图中不允许存在环,即包之间的结构必须是一个直接的五环图形。
-
稳定依赖原则
朝着稳定的方向进行依赖。
-
稳定抽象原则
包的抽象程度应该和其稳定程度一致。
7.1.4 面向对象分析
面向对象分析(OOA)的目的是为了获得对应用问题的理解。理解的目的是确定系统的功能、性能要求。
面向对象分析包含 5 个活动:认定对象、组织对象、描述对象间的相互作用、确定对象的操作、定义对象的内部信息:
-
认定对象(定义问题域)
-
组织对象
-
描述对象间的相互作用
-
确定对象的操作
-
定义对象的内部信息
7.1.5 面向对象设计(理解解决方案,系统的实现)
面向对象设计 (OOD)是将 0OA 所创建的分析模型转化为设计模型,其目标是定义系统构造蓝图。
OOD 在复用 OOA 模型的基础上,包含与 OOA 对应如下五个活动:
- 识别类及对象
- 定义属性
- 定义服务(行为和操作)
- 识别关系
- 识别包
7.1.6 面向对象测试
一般来说,对面向对象软件的测试可分为下列 4 个层次进行:
-
算法层
测试类中定义的每个方法,基本上相当于传统软件测试中的单元测试。
-
类层
测试封装在同一个类中的所有方法与属性之间的相互作用。在面向对象软件中类是基本模块,因此可以认为这是面向对象测试中所特有的模块测试
-
模板层
测试一组协同工作的类之间的相互作用,大体上相当于传统软件测试中的集成测试,但是也有面向对象软件的特点。
-
系统层
把各个子系统组装成完整的面向对象软件系统,在组装过程中同时进行测试。