code2读书笔记-第六章 可以工作的类

类是由一组数据和子程序构成的集合,这些数据和子程序共同拥有一组内聚的、明确定义的职责。

6.1 类的基础:抽象数据类型

抽向数据类型(ADT,abstract data type)是指一些数据以及对这些数据所进行的操作的集合

需要用到ADT的例子

假如你正在写一个程序,它能用不同的字体,字号和文字属性来控制显示在屏幕上的文本。程序的一部分功能是控制文本的字体。如果使用一个ADT,你就能有捆绑在相关数据上的一组操作字体的子程序。这些子程序和数据集合为一体,就是一个ADT。

如果不使用ADT,你就只能使用一种拼凑的方法来操作字体

使用ADT的益处

更多ADT示例

6.2 良好的类接口

创建高质量的类,第一步也可能是最重要的一步,就是创建一个好的接口。

好的抽象

抽象是一种以简化的形式来看待复杂操作的能力。

如果类的接口不能展现出一种一致的抽象,它的内聚性就很弱。应该将它的子程序重新组织到几个职能更专一的类里去,在这些类的接口中提供更好的抽象。

创建累的抽象接口的指导建议

良好的封装

封装是一个比抽象更强的概念。抽象通过提供一个可以让你忽略实现细节的模型来管理复杂度,而封装则强制阻止你看到细节。

这两个概念之所以相关,是因为没有封装时,抽象往往很容易被打破。要么就是封装与抽象两者皆有,要么就是两者皆失。

6.3 有关设计和实现的问题

给类定义合理的接口,对于创建高质量程序起到了关键作用。然而类内部的设计和实现也同样重要。这一节就来论述关于包含、继承、成员函数和数据成员、类之间的耦合性、构造函数、值对象与引用对象等问题。

包含(“有一个”的关系)

与包含相比,继承的论述要多得多,这是因为继承需要更多技巧,而且更容易出错,而不是因为继承要比包含更好。包含才是面向对象编程中的主力技术。

继承(“是一个”的关系)

继承的概念是说一个类是另一个类的一种特化。继承的目的在于,通过“定义能为两个或者更多派生类提供共有元素的基类”的方法写出更精简的代码。


为什么有这么多关于继承的规则
继承往往让你和程序员的首要技术使用(管理复杂度)背道而驰。下面总结一下何时可以使用继承,何时又该使用包含:

成员函数和数据成员

下面就有效地实现成员函数和数据成员给出一些指导建议:

构造函数

针对构造函数的这些建议对于不同的语言(c++、java和VB)都差不多。但对于析构函数而言则略有不同。

为了不确定的性能提高而增加复杂度是不妥的,因此面对拷贝时,优先深拷贝。实现浅拷贝除了要用到两种方法到需要的代码外,还需要增加很多代码用于引用计数、确保安全地复制对象、安全比较对象以及安全地删除对象等

6.4 创建类的原因

实际上创建类的理由远不止要为世界中的物体建模。下面列出一些创建类的原因:

应该避免的类


要点

目录