

我们可以清楚的看到,整个继承体系中static成员变量只有一份,无论是用p访问还是s访问,地址都一样,而像_name成员是两个不同的,所以地址也不一样。
七、多继承及其菱形继承问题
单继承:⼀个派⽣类只有⼀个直接基类时称这个继承关系为单继承。
多继承:⼀个派⽣类有两个或以上直接基类时称这个继承关系为多继承,多继承对象在内存中的模型是先继承的基类在前⾯,后⾯继承的基类在后⾯,派⽣类成员在放到最后⾯。(这里体现的是内存布局中的从上到下,地址由低到高)
类似于上面这种
菱形继承:菱形继承是多继承的⼀种特殊情况。菱形继承的问题,从下⾯的对象成员模型构造,可以看出菱形继承有数据冗余和⼆义性的问题,在Assistant的对象中Person成员会有两份。⽀持多继承就⼀定会有菱形继承,像Java就直接不⽀持多继承,规避掉了这⾥的问题,所以实践中我们也是不建议设计出菱形继承这样的模型的。
上面是一个菱形继承的代码
1.菱形继承的缺点很明显,总是会造成数据冗余的情况,最顶层的公共基类总是存在多份,浪费内存,数据不一。
2.访问歧义:在访问顶层基类成员时,需要指明是哪条继承路径,否则会报二义性错误。
3.顶层的构造函数被多次调用,逻辑容易出错。
虚继承会解决菱形继承造成的数据冗余,二义报错等情况。


此时Student与Teacher共用一个_name,但这是不好的,仍然不太建议。
八、继承和组合
public继承是⼀种is-a的关系。也就是说每个派⽣类对象都是⼀个基类对象。
组合是⼀种has-a的关系。假设B组合了A,每个B对象中都有⼀个A对象。
继承允许你根据基类的实现来定义派⽣类的实现。这种通过⽣成派⽣类的复⽤通常被称为⽩箱复⽤
(white-box reuse)。术语“⽩箱”是相对可视性⽽⾔:在继承⽅式中,基类的内部细节对派⽣类可
⻅ 。继承⼀定程度破坏了基类的封装,基类的改变,对派⽣类有很⼤的影响。派⽣类和基类间的依赖关系很强,耦合度⾼。
对象组合是类继承之外的另⼀种复⽤选择。新的更复杂的功能可以通过组装或组合对象来获得。对
象组合要求被组合的对象具有良好定义的接⼝。这种复⽤⻛格被称为⿊箱复⽤(black-box reuse),
因为对象的内部细节是不可⻅的。对象只以“⿊箱”的形式出现。 组合类之间没有很强的依赖关
系,耦合度低。优先使⽤对象组合有助于你保持每个类被封装。
优先使⽤组合,⽽不是继承。实际尽量多去⽤组合,组合的耦合度低,代码维护性好。不过也不太
那么绝对,类之间的关系就适合继承(is-a)那就⽤继承,另外要实现多态,也必须要继承。类之间的关系既适合⽤继承(is-a)也适合组合(has-a),就⽤组合。