2

私は多重継承の概念を調査していました (C++ を怒ってコーディングしてからほぼ 10 年が経ちましたが、単純にこの概念に学問的に興味を持っていました)。ウィキペディアでこのリファレンスを見つけました。

彼らがリストする MI に対する批判の 1 つは、「単一のクラスから複数回明示的に継承できない」ことです。私はこの声明について混乱しており、これが何を指しているのか 100% 確信が持てません。

確かに、クラスの継承はクラスの構造を記述しており、同じクラスから複数回継承することは、同じクラスの契約を繰り返すだけなので、批判を正当化するためにどのような利点があるかわかりません。明示的な継承は、クラスの関数とプロパティの複数のインスタンスを想定しますか?

この批判が何を指しているのか、そして多重継承が有効な言語では暗黙のうちに利用できない理由を理解したいと思います。

4

6 に答える 6

6

これはダイヤモンド問題と呼ばれます。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 に値を入れる場合、どこに保存する必要がありますか? 2 つのフィールド B(A).f と C(A).f を 1 つにマージする必要がありますか、それとも別々のままにする必要がありますか? B と C で A のメソッド x をオーバーライドする場合、Dx() は何をすべきでしょうか? 両方に電話しますか?どの順番で?戻り値はどうですか?

于 2009-02-10T12:49:44.483 に答える
1

多重継承は、オブジェクト指向プログラミングのGOTOです。これは、初期のOOP言語(C ++など)で採用されたアプローチが原因で発生しました。右手ではうまく機能しますが、他のほとんどの場合は混乱します。

OOPの主要な目標の1つは、行動の再利用でした。これはキメラであることが判明しました。便利な場合もありますが、それ以外の場合、私たちが本当に関心を持っているのは、オブジェクトがどのように相互作用するかを定義することです。デザインパターンで、継承ではなくインターフェイスを使用するパターンの数を確認します。

インターフェースの実装とそれに続く明示的な集約は、多重継承が行うのと同じことを行うためのより明確でより保守しやすい方法です。ほぼすべてのOOPにはインターフェースを定義する何らかの方法があり、ほぼすべてのOOPはオブジェクトを一緒に集約できます。ただし、OOPは、多重継承によって発生する問題(ダイヤモンド問題など)を微妙に異なる方法で処理します。GOTOのように、複数の継承を使用してコードを調べる場合、何が起こっているのかが明確ではありません。ただし、GOTOと同様に、さまざまな状況で役立ちます。

私にとって、難しい言語構成を使用する際の主な考慮事項は、アプリケーションを長期間維持する必要があるかどうかです。そうする場合は、もう少しプログラミングが必要になったとしても、最も明確で保守が容易なアプローチを選択します。他のすべてのように、それは判断の呼びかけです。ほとんどの場合、私たちがこれまで考えていたよりもはるかに長く開発したプログラムに固執することになります。

于 2009-02-10T13:31:05.757 に答える
1

同様に、私は C# に切り替えてから 5 年以上 C++ を怒ってコーディングしていません。多重継承をあまり使用したかどうかはよく覚えていませんが、特にインターフェイスにコーディングできることと、最近は構成をより多く使用していることから、それを見逃すことはありません。

しかし、これまでで最高の OO の本では- おそらく ;) - Betrand Meyer は多重継承をうまく弁護しています。彼はここでも同様の防御を行います。

于 2009-02-10T11:52:33.700 に答える
1

クラス Car はその 4 つの車輪から継承できない (たとえば、クラス Wheel を 4 回継承する) ことを意味していると思います。[同じ Wikipedia ページの C++ スタンザを参照してください]

しかし、継承はサブタイピングを表現するためにあり、「単一の型からの複数のサブタイピング」は存在しないため、この「省略」は実際にはプラスの機能だと思います。この「明示的な多重継承」は、単純な構成に勝るものはありません。

于 2009-02-10T11:53:16.957 に答える
0

実際、C++ では、クラスは同じクラスから複数回継承できます。

クラスA {};

クラス B : パブリック A ();

クラス C : パブリック A ();

クラス D : パブリック B、パブリック C {};

これで、D は A の 2 つのコピーで終わります。これは一般に「悪い考え」と見なされ、C++ はそれを制御するための仮想継承を提供します。

于 2009-02-10T12:00:03.090 に答える