多重继承批评

发布于 2024-07-13 14:27:04 字数 403 浏览 5 评论 0原文

我正在研究多重继承的概念(自从我愤怒地编写 C++ 代码以来已经快有 10 年了,并且只是对这个概念产生了学术上的兴趣)。 我在维基百科上找到了这个参考

他们列出的对 MI 的批评之一是“无法从单个类显式多次继承”。 我对这个说法感到困惑,并不能 100% 确定它指的是什么。

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

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

I was investigating the concept of Multiple Inheritance (it's been almost 10 years since I have coded C++ in anger, and was simply academically interested in the concept). I found this reference on Wikipedia.

One criticism of MI they list is "Not being able to explicitly inherit multiple times from a single class". I'm confused about this statement, and not 100% sure what this is referring to.

Surely a class inheritance describes the structure of a class, and to inherit multiple times from the same class would simply reiterate the same class contract, so I can't see what benefit it would give to justify the criticism. Would explicit inheritance suppose multiple instances of the class functions and properties?

I would like to understand what this criticism is referring to, and why it is implicitly unavailable to Multiple Inheritance enabled languages.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

稚然 2024-07-20 14:27:04

这称为钻石问题。 大多数允许 MI 的现代语言都有一个解决方案。

简而言之,您有这个类树:

class A { public int f = 0; };

class B extends A { f = 1; };

class C extends A { f = 2; };

class D extends B, C {};

Df 将打印什么? 如果将一些值放入 Df 中,它应该存储在哪里? 两个字段 B(A).f 和 C(A).f 应该合并为一个还是应该保持独立? 如果你在B和C中重写A的方法x,Dx()应该做什么? 两个都打电话吗? 按什么顺序? 那么返回值呢?

This is called the Diamond Problem. Most modern languages that allow MI have a solution for this.

In short, you have this class tree:

class A { public int f = 0; };

class B extends A { f = 1; };

class C extends A { f = 2; };

class D extends B, C {};

What will D.f print? If you put some value into D.f, where should it be stored? Should the two fields B(A).f and C(A).f be merged into one or should they stay separate? If you override a method x of A in B and in C, what should D.x() do? Call both? In which order? What about the return value?

浮世清欢 2024-07-20 14:27:04

我认为他们的意思是 Car 类不能继承它的四个轮子(例如继承 Wheel 类的四倍)。 [参见同一维基百科页面上的 C++ 节]

然而,我认为这种“省略”实际上是一个积极的特性,因为继承是用来表达子类型的,并且不存在“单一类型的多个子类型”。 这种“显式多重继承”并不比简单组合更好。

I think they mean that a class Car cannot inherit from its four wheels (eg. inherit four times the class Wheel). [See the C++ stanza on the same Wikipedia page]

However, I think this "omission" is actually a positive feature, because inheritance is there to express subtyping, and there is no "multiple subtyping from single type". This "explicit multiple inheritance" would be no better than simple composition.

无可置疑 2024-07-20 14:27:04

同样,我已经 5 年多没有愤怒地编写 C++ 代码了,现在已经改用 C# 了。 我真的不记得我是否经常使用多重继承,但我并没有错过它,特别是因为我可以编写接口代码并且这些天我更多地使用组合。

然而,在有史以来最好的面向对象的书中 - 可能;) - Betrand Meyer 提出多重继承的良好防御。 他还在此处进行了类似的辩护。

Similarly I've not coded C++ in anger for over 5 years now having switched to C#. I can't really remember whether I used multiple inheritance much, but I don't miss it, especialy as I can code to interfaces and that I use composition more these days.

However, in the best OO book ever - probably ;) - Betrand Meyer makes a good defense of multiple inheritance. He also makes a similar defense here.

韵柒 2024-07-20 14:27:04

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

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

但是,这六种语言允许类从多个接口继承,从而重现了所提到的一些问题,同时避免了其他问题。

坦白说,我不知道你问题中这句话的作者的意图是什么。 恕我直言,这只是一篇写得不好的文章中含糊不清的另一个例子。

I think the problem is with that particular Wikipedia article. It contains more than one awkward or vague statement, such as these jewels:

Tcl allows multiple parent classes- their serial affects the name resolution for class members.

and

However, these six languages allow classes to inherit from multiple interfaces, recreating some of the problems mentioned while avoiding others.

I frankly don't know what the author intended by the sentence in your question. It's just another example of vagueness in a poorly-written article, IMHO.

倾听心声的旋律 2024-07-20 14:27:04

多重继承是面向对象编程的GOTO。 它的出现是由于早期 OOP 语言(C++ 等)采用的方法。 它在右手中效果很好,但在其他大多数情况下却令人困惑。

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

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

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

Multiple Inheritance is the GOTO of object oriented programming. It arose because of the approaches adopted by the early OOP langauges (C++,etc). It works well in the right hand, but it confusing most of the other times.

One of the leading goals of OOP was reuse of behavior. This turned out to be a chimera. Useful in some cases but in rest of the cases what we are really interested in is defining how objects interact. Look at how many patterns in Design Patterns use interface as opposed to inheritance.

Implementing Interfaces, followed by explicit Aggregation are clearer more maintainable ways of doing the same things that multiple inheritance does. Nearly all OOP have some method of defining a interface, nearly all OOP can aggregate objects together. However OOP handle the issues raised by multiple inheritance (the Diamond Problem, etc) in subtle different ways. Like the GOTO when you look over code using multiple iheritance it is not clear what is going on. However like GOTO it can be useful in different circumstances.

For me the primary consideration for using any difficult language construction is whether I have to maintain the application over the long haul. If I do then I opt for the clearest more easily maintained approach even if takes a little more programming now. Like everything else it is a Judgment call. Note that most of the time we wind up sticking with the program we developed far longer than we ever figured.

蓦然回首 2024-07-20 14:27:04

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

class A {};

B类:公共A();

C类:公共A();

类D:公共B,公共C{};

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

Actually, in C++ a class can inherit multiple times from the same class:

class A {};

class B : public A ();

class C : public A ();

clsss D : public B, public C {};

Now D ends up with two copies of A. This is is generally regarded as "a bad idea" and C++ provides virtual inheritance to control it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文