9.16 章节小结
面向对象的程序设计能力的关键之一是通过继承实现软件的复用。
程序员可以让新类继承已定义基类的数据成员和成员函数,而不必重新编写新的数据成员和成员函数。这种新类称为派生类。
对于单一继承,派生类只有一个基类。对于多重继承,派生类常常是从多个基类派生出来的,这些基类之间可能毫无关系。
派生类通常添加了其自身的数据成员和成员函数,因而通常比基类大得多。派生类比基类更具体,它代表了一组外延较小的对象。
派生类不能访问其基类的private成员,否则会破坏基类的封装性。但是,派生类能够访问基类的public成员和protected成员。
派生类的构造函数总是先调用其基类构造函数来初始化派生类中的基类成员。
调用析构函数的次序和调用构造函数的次序相反,因此派生类析构函数在基类析构函数之前调用。
利用继承能够实现软件复用。软件复用缩短了程序的开发时间,促使开发人员复用已经测试和调试好的高质量的软件。
可以用现有的类库实现继承。
将来有一天,软件也可以像如今的硬件一样用标准的可复用组件进行构造。
派生类不必访问基类的源代码,但是需要知道基类的接口和能够连接到基类的目标代码。
派生类对象可作为其public基类的对象处理,但是反过来不行。
基类和派生类之间具有层次关系。
一个类可以单独存在,但是当利用继承机制使用该类时,该类就成为给其他类提供属性和行为的基类,或者成为继承其他类的属性和行为的派生类。
继承层次的深度在特定系统的限制范围之内是任意的。
层次结构是管理和弄清复杂问题的有用工具。随着软件日益复杂化,C++提供了支持层次结构的继承和多态性机制。
程序员可以用显式类型转换把基类指针转换为派生类指针。但是,如果要复引用该指针,那么在转换前首先应该把它指向某个派生类的对象。
protected访问是介于public访问和private访问之间的中间层次。基类的protected成员只能被基类的成员和友元以及派生类的成员和友元访问,没有其他函数能访问基类的protected成员。
protected成员能用来扩展对派生类的访问权限,而拒绝非类成员函数和非友元函数的访问权。
通过在派生类名后放置冒号并紧跟逗号分隔的基类列表可以用来指明多重继承。在派生类构造函数调用基类构造函数时使用成员初始化值的列表。
从基类派生一个类时,基类可被声明为public、protected或者private。
从public基类派生一个类时,基类的public成员成为派生类的public成员,基类的protected成员成为派生类的protected成员。
从protected基类派生一个类时,基类的public和protected成员都成为派生类的Protected成员。从private基类派生一个类时,基类的public和protected成员均成为派生类的private成员。
基类既可能是派生类的直接基类,也可能是派生类的间接基类。在声明派生类时,派生类的首部要显式地列出直接基类。间接基类不是显式地列在派生类的头部,而是沿着类的多个层次向上继承。
不适合派生类的基类成员可以在派生类中重新定义。
区分是关系和有关系是很重要的。在是关系中,派生类的对象也以作为基类的对象处理。而有关系中,一个类的对象拥有作为其成员的其他类的对象。是关系是一种继承,有关系是一种复合。
派生类对象可以赋给基类对象。由于派生类具有每一个基类成员,这种赋值是有意义的。
指向派生类对象的指针可以隐式地转换为指向基类对象的指针。
使用显式强制转换可以将基类指针转换为派生类指针,指向的目标应该是派生类的对象。
基类描述了共性。所有从基类派生出来的类都继承了基类的功能。在面向对象的设计过程中,设计者先寻求并提取出构成所需基类的共性,然后再通过继承从基类派生出超出基类功能的定制派生类。
因为派生类中没有列出所有的成员,所以浏览一组派生类的声明会令人迷惑,当派生类的声明中没有列出继承来的成员时更是如此,但是派生类中确实存在继承来的成员。
有关系通过复合现有的类建立了新类。
知道关系是对象包含其他对象的指针或引用,因而知道存在这些对象。
成员对象构造函数以声明对象的顺序调用。对继承关系而言.基类构造函数以指定的继承顺序调用并且在调用派生类构造函数之前调用。
对于一个派生类对象,先调用基类的构造函数,然后调用派生类的构造函数(也许调用成员对象的构造函数)。
当取消派生类对象时,析构函数的调用顺序与调用构造函数的顺序相反,即先调用派生类的析构函数,然后调用基类的析构函数。
一个类可以从多个基类派生而来,这种派生称为多重继承。
在继承指示符即冒号(:)后跟上用逗号分开的基类列表表示了多重继承。
派生类构造函数用成员初始化值语法调用其每个基类的构造函数。基类构造函数按其在继承中声明的基类顺序依次调用。