2009-02-10 44 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一樣,它可以在不同的情況下有用。

對我來說,使用任何困難的語言結構的主要考慮因素是我是否必須長期維護應用程序。如果我這樣做,那麼即使現在需要更多的編程,我也會選擇最清晰,更容易維護的方法。像所有其他事情一樣,這是一個判決電話。請注意,大部分時間我們都會堅持我們開發的程序比我們想象的要長得多。