一、单继承存在的问题
假设你使用Animal类已经有一段时间后,并将类层次结构分为了鸟类和哺乳动物。Bird类包括成员函数fly,从Mammal类派生出了Horse类,Horse类包括成员函数whinny和gallop.
现在需要一个飞马对象Pegasus:一种介于马和鸟之间的动物。它可能包含成员函数fly和whinny。这是使用单继承就会陷入困境。
第一种解决方法:从Horse类派生出Pegasus,将fly复制到Pegasus中。这样不得不使维护人员修改fly,需要修改两处地方。但是这种方法,不能将Pegasus解释为一个
Bird对象。
第二种方法,将Horse类gallop方法重命名为move,然后在Pegasus中覆盖move使其完成fly工作。如
Pegasus::move(long distance)
{
if(distance > veryFar)
fly(distance);
else
gallop(distance);
}
不足之处就是,当飞马短距离也想飞,这就不好办了。
第三种方法,提升。将所需的函数放到类层次结构较高的位置。如果公用的方法变多了,基类就非常庞大。
第三种方法:向下转换。把fly方法留在Pegasus中,仅当指针指向Pegasus对象时才调用它。使用dynamic_cast来检查。
二、多重继承
语法:
class DerivedClass : public BaseClass1,public BaseClass2
在内存中创建DerivedClass时,两个基类都将成为Pegasus对象的组成部分。
有多个基类需要处理的问题:
1 如果碰巧两个基类都有同名的虚函数或数据将如何处理?完全限定法
2 如果调用多个基类构造函数?
CPegasus(COLOR color, bool migration, HANDS height,int age):
CHorse(color, height,age),
CBird(color, migration,age)
3 如果多个基类都从同一个类派生而来又将如何呢?
完全限定法pPeg-> CHorse::getColor()
4 从共同基类继承,如果调用共同基类的方法
完全限定法CHorse::getAge()
或者虚继承
三、虚继承
如果Horse和Bird有相同的基类,决定使用哪个方法,是随意的。不过,可以告诉C++,不想使用共同基类的两个副本,而只是想要一个共同基类的副本。可让Animal成为Horse和Bird的续基类。只需要在声明中添加关键字virtual即可,Animal不用修改。对Pegasus要做大量修改。
通常,类的构造函数只初始化自己的变量及其基类,但虚继承的基类例外,它们由最后的派生类进行初始化。因此,Animal不是由Horse和Bird初始化,而是由Pegasus初始化。Horse和Bird必须在其构造函数初始化Animal,但是创建Pegasus对象时,这些初始化被忽略了。
class CHorse:virtual public CAnimal
class CBird:virtual public CAnimal
CPegasus(COLOR color, bool migration, HANDS height,int age):CHorse(color, height,age),
CBird(color, migration,age),CAnimal(age*2)
四、多重继承存在的问题
开发多继承类层次结构比开发单继承层次结构更困难且风险更大,且调试难度较大。诸如Java和C#等语言都不支持多重继承。
五、混合(功能)类
在多重继承和单继承之间的一种折中方案是使用混合类(mixin)。混合类增加专用功能而不会增加大量方法或数据的类。
功能类与其他类的唯一区别是:功能类没有或只有很少的数据。