好久不见,距离上次更新继承篇已经过去一段事件,今天抽空把坑填上。那么序言就不介绍了,不太理解继承概念的可以看看我之前写的继承入门篇,好的,我们废话不多说,直接发车。
继上次的子承父类继续说,继承不仅仅可以单独继承一个类,也可以继承多个类。这个有点类似设计模式中的桥接模式(设计模式之后再说),也就是我们常说的多继承,一个类共同用有两个类的特性,当有这种场景出现时就可以使用多继承了,如下图所示:
如上图所示,AB类同时公有继承了A和B两个类,那么此时AB类就同时具有A和B的成员函数以及成员变量,怎么使用呢?很简单,父类怎么调用,子类就怎么调用,还是一样的,如下图所示:
那么,如果父类和子类方法名称一样怎么办? 岂不是调用的时候无法知道调用谁的了?比如以下情况:
唉?为什么我调用funBPlay方法,怎么打印的是C呢?为什么不是B呢?明明已经继承了B类的funBPlay方法了啊?这是为什么呢?是运气吗?实际上不是,在继承中,如果子类和父类出现重名方法,那么会优先调用子类的方法。那么怎么解决方法名称重复的问题呢?其实很简单,使用类名限定就可以了,如下所示:
怎么样?是不是很神奇呢?在实际的开发中,我们一般不会这样去写,因为C++提供了更变态的特性,那就是多态,多态可以使接口进行完全覆盖,也可以让方法在合适的时机被调用,完全不需要显示指定类名限定。那么看到这里,大家可能觉得多继承不过如此嘛。那么如果我稍稍修改一下呢?
class A
{
public:
A(){}
~A(){}
void play(){ cout<<a<<endl;}
private:
int a;
};
class ASon1:public A
{
public:
ASon1(){}
~ASon1(){}
void play(){ cout<<a<<endl;}
private:
int a;
}
class ASon2:public A
{
public:
ASon2(){}
~ASon2(){}
void play(){ cout<<a<<endl;}
private:
int a;
}
class Agrandson:public ASon1,public ASon2
{
public:
Agrandson(){}
~Agrandson(){}
void play(){ cout<<a<<endl;}
private:
int a;
}
各位,如果我使用这种继承,你们该如何应对呢?这就是虚继承没有出现之前的业界难点,菱形继承。java中为了防止这种情况出现已经不允许再使用多继承了,那么这样继承会造成什么影响呢?如下所示:
答案显而易见,两次。同一个变量怎么能被继承两次呢?这很明显是不符合规范的,所以为了解决这个问题,C++推出了虚拟继承virual。
那么请大家思考,如果这样的类拿去使用的话,会造成什么影响呢?答案我会在下次高级篇进行公布,好的,这次的内容就到此结束了,希望各位知其然知其所以然,我是程序员萧炎,一位资深C++程序员,我们下次再见。