10.4 抽象基类和具体类
当我们把类看作一种数据类型时,我们通常认定该类型的对象是要被实例化的。但是,在许多情况下,定义不实例化为任何对象的类是很有用处的,这种类称为 抽象类 (abstract class)。因为抽象类要作为基类被其他类继承,所以通常也把它称为 抽象基类(abstract base class)。抽象基类不能用来建立实例化的对象。
抽象类的惟一用途是为其他类提供合适的基类,其他类可从它这里继承和(或)实现接口。能够建立实例化对象的类称为具体类(concrete class )。
例如,我们可以建立抽象基类 TwoDimensionalObject,然后从它派生出具体类 Square、Circle 和 Triangle 等等,也可以建立抽象基类 ThreeDimensionalObject,然后从它派生出具体类 Cube、Sphere 和 Cylinder 等等。这些抽象基类表述的含义因为太广泛而定义不出实在的对象。如果要建立实例对象,则需要含义更加明确的类,,这就是所谓的 具体类。具体类具有足以能够建立实例化对象的明确含义。
如果将带有虚函数的类中的一个或者多个虚函数声明为纯虚函数,则该类就成为抽象类。纯虚函数是在声明时 初始化值 为0的函数,例如:
virtual float earnings() const = O; // pure virtual
软件工程视点 10.4
如果某个类是从一个带有纯虚函数的类派生出来的,并且没有在该派生类中提供该纯虚函数的定义,则该虚函数在派生类中仍然是纯虚函数,因而该派生类也是一个抽象类。
常见编程错误 10.1
试图实例化一个抽象类对象(即包合一个或者多个纯虚函数的类)是一种语法错误。
一个类层次结构中可以不包含任何抽象类,但是正如以后会看到的,很多良好的面向对象的系统,其类层次结构的顶部是一个抽象基类。在有些情况中,类层次结构顶部有好几层都是抽象类。
形状类的层次结构就是一种典型的范例。我们可以在该层次结构的顶部建立抽象基类shape,在往下的一层中还可以再建立两个抽象基类,即二维形状类 TwoDimensionalShape 和三维形状类 ThreeDimensionalShape,再往下我们就可以开始定义二维形状的具体类如圆形类和正方形类以及三维形状的具体类如球类和立方体类等等。