2009-02-10 85 views
2

我正在研究多重继承的概念(自从我编写C++的时候已经差不多有10年了,而且在学术上对这个概念感兴趣)。我在Wikipedia上发现这个reference多重继承批评

他们列举的一个对MI的批评是“不能从一个班级多次显式继承”。我对这个陈述感到困惑,而不是100%确定这是指什么。

当然,类继承描述了一个类的结构,并且从同一个类继承多次只会重申相同的类合同,所以我看不出有什么好处来证明批评的合理性。显式继承是否会假设类函数和属性的多个实例?

我想了解这种批评所指的是什么,以及为什么它隐式地启用了多种继承的语言。

回答

1

我认为他们的意思是一辆汽车不能从它的四个车轮继承(例如,继承四次车轮)。然而,我认为这个“省略”实际上是一个积极的特性,因为继承是用来表示子类型的,并且没有“单一类型的多重子类型”。这种“显式多重继承”不会比简单的组合更好。

+0

这就是我的想法,因此我的困惑。我同意,将它作为一个“特征”包含在内是错误的,因为它肯定违背了我对OO – johnc 2009-02-10 12:47:00

+0

的理解。“_class汽车不能从它的四个车轮继承(例如继承四次Wheel_的类型”嗯,它可以,只是不直接,有趣的想法;) – curiousguy 2011-11-01 03:06:34

1

同样,我已经在切换到C#的情况下,在愤怒中编写了C++超过5年。我真的不记得我是否使用了多重继承,但我不会错过它,特别是我可以编写接口,并且现在我更多地使用组合。

但是,在the best OO book ever - 可能;) - Betrand梅耶是多重继承的良好保护。他也做出类似的防守here

0

实际上,在C++类可以从同一类继承多次:

类A {};公共A();公共A();公共A();公共A();公共A();公共A();公共A();公共A();公共A();公共A C类:public A();类C:公共A();公共A();公共A();公共A();公共A();公共A();公共A();公共A

clsss D:public B,public C {};

现在D结束了两个A的副本。这通常被认为是“一个坏主意”,C++提供虚拟继承来控制它。

+0

不,这不是。 “钻石继承”在链接的维基百科页面中列为单独问题。 – 2009-02-10 12:20:07

1

我认为问题在于那篇特定的维基百科文章。它包含不止一个尴尬或模糊的陈述,如这些珠宝:

Tcl允许多个父类 - 它们的序列会影响类成员的名称解析。

然而,这些六种语言允许类从多个接口继承,再造一些,同时避免其他人提到的问题。

我坦率地不知道作者在你的问题中的意图是什么。这仅仅是一个写得很差的文章中模糊的例子,恕我直言。

6

这被称为Diamond Problem。大多数允许MI的现代语言为此提供了解决方案。

总之,你有这样的分类:

class A { public int f = 0; }; 

class B extends A { f = 1; }; 

class C extends A { f = 2; }; 

class D extends B, C {}; 

会有什么D.f打印?如果你把一些价值放在D.f中,它应该存储在哪里? B(A).f和C(A).f这两个字段应该合并为一个还是应该保持独立?如果你在B和C中重写A的方法x,D.x()应该做什么?同时打电话?按何种顺序?什么是回报价值?

+0

那是什么语言? – curiousguy 2011-11-01 03:09:45

1

多继承是面向对象编程的GOTO。它起因于早期的OOP语言(C++等)采用的方法。它在右手中运行良好,但其他时间大部分时间都会混淆。

OOP的主要目标之一是重用行为。这原来是一个嵌合体。在某些情况下有用,但在其他情况下,我们真正感兴趣的是定义对象如何相互作用。看看设计模式中有多少模式使用接口而不是继承。

实现接口,然后显式聚合更清晰,更可维护多种继承所做的相同事情。几乎所有的OOP都有一些定义接口的方法,几乎​​所有的OOP都可以将对象聚合在一起。然而,OOP以微妙的不同方式处理由多重继承(钻石问题等)引发的问题。使用多重继承来查看代码时,像GOTO一样,不清楚发生了什么。然而像GOTO一样,它可以在不同的情况下有用。

对我来说,使用任何困难的语言结构的主要考虑因素是我是否必须长期维护应用程序。如果我这样做,那么即使现在需要更多的编程,我也会选择最清晰,更容易维护的方法。像所有其他事情一样,这是一个判决电话。请注意,大部分时间我们都会坚持我们开发的程序比我们想象的要长得多。