对象的类和对象的类型
理解对象的类(class)与对象的类型(type)之间的差别非常重要。
对象的类:定义了对象是怎样实现的, 同时也定义了对象的内部状态和操作的实现。
对象的类型:对象的类型只与它的接口有关, 接口即对象能响应的请求的集合。一个对象可以有多个类型, 不同类的对象可以有相同的类型。
原则性知识点:
1. 针对接口编程,而非实现编程
- 类继承是一个通过复用父类功能而扩展应用功能的基本机制。
它允许你根据旧对象快速定义新对象。
允许你从已存在的类中继承所需要的绝大部分功能, 从而几乎无需任何代价就可以获得新的实现。
然而, 实现的复用只是成功的一半, 继承所拥有的定义具有相同接口的对象族的能力也是很重要的 (通常可以从抽象类来继承)。
为什么?
因为多态依赖于这种能力。
- 当继承被恰当使用时, 所有从抽象类导出的类将共享该抽象类的接口**
这意味着子类仅仅添加或重定义操作, 而没有隐藏父类的操作。这时, 所有的子类都能响应抽象类接口中的请求, 从而子类的类型都是抽象类的子类型。
只根据抽象类中定义的接口来操纵对象有以下两个好处:
- 客户无须知道他们使用对象的特定类型, 只须对象有客户所期望的接口。
- 客户无须知道他们使用的对象是用什么类来实现的,他们只须知道定义接口的抽象类。这将极大地减少子系统实现之间的相互依赖关系, 也产生了可复用的面向对象设计的如下原则:
2. 优先使用对象组合, 而不是类继承
对象组合是通过获得对其他对象的引用而在运行时刻动态定义的。
组合要求对象遵守彼此的接口约定, 进而要求更仔细地定义接口, 而这些接口并不妨碍你将一个对象和其他对象一起使用。
这还会产生良好的结果: 因为对象只能通过接口访问, 所以我们并不破坏封装性;
只要类型一致, 运行时刻还可以用一个对象来替代另一个对象; 更进一步, 因为对象的实现是基于接口写的, 所以实现上存在较少的依赖关系。
对象组合对系统设计还有另一个作用, 即优先使用对象组合有助于你保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模, 并且不太可能增长为不可控制的庞然大物。另一方面, 基于对象组合的设计会有更多的对象(而有较少的类), 且系统的行为将依赖于对象间的关系而不是被定义在某个类中。