继承的定义及工作方式 2 类的继承访问特性
|
3 函数的隐藏与覆盖 我们已经知道了函数的重载是怎么回事,重载的函数名字相同,但它们的参数个数和类型不同。函数的隐藏和覆盖,与函数的重载不同,它们只是在继承的情况下才存在。 如果在派生类中定义了一个与基类同名的函数,也就是说为基类的成员函数提供了一个新的定义,有两种情况: ◇ 在派生类中的定义与在基类中的定义有完全相同的信号(signature)(即参数个数与类型均相同)和返回类型,对于普通成员函数,这便称之为重定义;而对于虚成员函数(在本章的后面介绍),则称之为覆盖。 ◇ 在派生类中,改变了成员函数参数表与返回类型。此时会出现什么情况? 在派生类中重定义基类的成员函数,会隐藏基类的该成员函数,例如:
b.a::a(1); b.a::a(1.0); 4 不合适的继承 继承和派生有一个基本的原则,就是基类对象能够使用的地方,也能用同样的方法使用派生类的对象。 下面是一个破坏了这个原则的实例,BoundedStack时从Stack派生的,Stack类支持基本的栈操作,即压入一个元素到栈中和从栈中弹出一个元素,如例11-8。 在该类中,隐含push成员函数总能压入一个新的元素到栈中。有时,我们可能需要只能压入固定元素个数的栈。为了复用Statck类的实现,从Statck类派生了一个BoundedStack类,如例11-9。 但是,这破坏了上面提到的基本的原则:基类对象能够使用的地方,派生类对象也能够被使用。例如,假定BoundedStack的capacity成员设置为5,即栈中最多只能有5个元素,则压栈次数超过5,则会出错。 之所以从Statck派生BoundedStack,只是为了复用Statck类的代码,其实,我们也可以用组合的方法复用代码,所谓组合是指用一个类的对象作为另一个类的数据成员,如例11-9。 现在我们对这个原则可能还理解不深,在学习了多态的概念后,对这个原则会有更深的理解。
当某一个类A希望拥有另一个类B的性能,但又不希望类B的接口成为类A的接口,或者类B是类A的一个组成部分,就使用组合,而不要使用继承。例如,一台电脑可以由一个主机,一个显示器和一个键盘组成。用类描述可以是:
|
5 多继承 我们前面介绍的内容中,一个派生类继承一个基类,我们称之为单继承。C++也支持多继承,即一个派生类继承多个基类,参见图11-1。
|