前些天在《Head First设计模式》上看到了这一原则。
书上的例子非常好,鸭子的飞行行为和嘎嘎叫的行为确实可以从父类继承得到
但是如果出现橡皮鸭子,它不会叫也不会飞,如果要把它归类为鸭子,那么代码就有得写了(更详细内容参见该书)。

今天突然想起另外一个问题,某天看到一句话:Java采用接口,避免了多继承带来的问题。
于是去Google了一下多继承存在的问题,然后就发现,除了继承带来的冗余数据和方法之外,另一个大问题就是钻石问题。
@ 2009-05-26 下面举的例子有点问题,详情参见篇后sandy的评论
话说端午节快到了,该是吃粽子的时候了——
我们知道米饭和豆沙都是(继承)食品,然后我们用米饭包住豆沙放在锅里蒸一下,我们就得到了(派生)粽子。
这样的结构是:
    食品
    /     \
米饭   豆沙
    \     /
     粽子
这是一个菱形,于是被成为钻石问题:如果食品里有一个成员 "好吃程度",那么粽子的"好吃程度"是继承自哪一个呢?
在C++这个支持多继承的语言里面,如果直接使用
粽子 粽子a;
cout << 粽子a.好吃程度 << endl;

然后就会发现编译器(g++)报错:对成员"好吃程度"的请求有歧义(ambiguous)。
不过好在有3个解决方式:
1。重新定义一个好吃程度覆盖米饭和豆沙的好吃程度。
2。指明是哪个父类的好吃程度:例如  粽子a.米饭::好吃程度  或者  粽子a.豆沙::好吃程度
3。使用虚拟继承(虚基类),详情请STFW。

于是我突然想到其实这里如果使用"多用组合,少用继承"的设计原则(很像解决方法2),那么问题就解决拉:
class 粽子: public 食品{
private:
    米饭 米饭a;
    豆沙 豆沙a;
public:
    粽子(){
        好吃程度 = (米饭a.好吃程度 + 豆沙a.好吃程度) / 2; //其实我觉得豆沙a的权值应该大些=.=
    }
};

当然这只是一个很初步的想法,代码也非常不严谨,谨以此抛砖引玉,欢迎交流。



欢迎扫码关注:




转载请注明出自 ,如是转载文则注明原出处,谢谢:)
RSS订阅地址: https://www.felix021.com/blog/feed.php