第14章 继承和组合

C++最重要的特征之一是代码重用。但是如果希望更进一步,就不能仅仅用拷贝代码和修改代码的方法,而是要做更多的工作。

在C中,这个问题未能得到很好的解决。而在C++中,这可以通过类的方法解决。我们通过创建新类来重用代码,而不是从头创建它们。这样,便可以使用别人已经创建好并经过调试的类。

关键技巧是使用这些类,但不修改已存在的代码。在本章中,我们将看到两种完成这项任务的方法。第一种方法很直接:我们简单地在新类中创建已存在类的对象。因为新类是由已存在类的对象组合而成,所以这种方法称为组合(composition)。

第二种方法要复杂些。我们创建一个新类作为一个已存在类的类型。我们不修改已存在的类,而是采取这个已存在类的形式,并将代码加入其中。这种巧妙的方法称为继承(inheritance),其中大量的工作是由编译器完成。继承是面向对象程序设计的基石,而且它还有另外的含义,我们将在第15章中探讨它的另外含义。

在语法上和行为上,组合和继承大部分是相似的(它们都是在已存在类型的基础上创建新类型的方法)。在本章中,我们将学习这些代码重用机制。

14.1 组合语法

实际上,我们一直都在用组合创建类,只不过是在用内建数据类型(有时用string)组合新类。其实使用用户定义类型组合新类同样很容易。

考虑下面这个在某种意义上是有价值的类:

第14章 继承和组合 - 图1

在X类中,数值成员是私有的,所以将类型X的一个对象作为公共对象嵌入到一个新类内部,这是绝对安全的。这样就使得新类的接口很简单,

第14章 继承和组合 - 图2

第14章 继承和组合 - 图3

访问嵌入对象(称为子对象)的成员函数只需再一次的成员选择。

更常见的是把嵌入的对象设为私有,因此它们将成为内部实现的一部分(这意味着如果我们愿意,可以改变这个实现)。新类的公有接口函数包括了对嵌入对象的使用,但没有必要模仿这个对象的接口。

第14章 继承和组合 - 图4

这里,permute()函数是通过新类的接口执行的,但X的其他的成员函数是在新类的成员Y内执行的。