标题:设计原则: 多用组合,少用继承。 出处:Felix021 时间:Mon, 25 May 2009 14:28:21 +0000 作者:felix021 地址:https://www.felix021.com/blog/read.php?1611 内容: 前些天在《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的权值应该大些=.= } }; 当然这只是一个很初步的想法,代码也非常不严谨,谨以此抛砖引玉,欢迎交流。 Generated by Bo-blog 2.1.0