本格的なクラスで使用される場合、多重継承には多くの問題がありますが、それらはすべて曖昧さを中心に展開します。
あいまいさは、いくつかの異なる方法で現れます。
- 同じfieldを持つ2つの基本クラスが
x
あり、派生型がを要求する場合x
、何が得られますか?
- 2つの
x
変数の型が一致しない場合は、推測できます。
- それらが同じ型である場合、同じ変数にマージしようとすることができます。
- あなたは常に奇妙な完全修飾名としてそれらを公開することができます。
f
同一のシグネチャを持つ同じ関数を持つ2つの基本クラスがあり、誰かがを呼び出すとf
、どちらが呼び出されますか?
- 2つの基本クラスが別の共通の仮想祖先を共有している場合(ダイヤモンドの問題)。
- 関数に異なるが互換性のある署名がある場合はどうなりますか?
- 2つの基本クラスでクラスを構築するとき、どの基本クラスのコンストラクターが最初に呼び出されますか?殺されたオブジェクトを破壊すると?
- オブジェクトをメモリにレイアウトするとき、どのように一貫してそれを行いますか?
- これらすべてのケースを3つの基本クラスでどのように処理しますか?10?
また、動的ディスパッチ、型推論、パターンマッチングなど、言語が完全なクラスの多重継承をサポートしている場合により困難になるものについてはあまり知らないことは無視されます。
特性またはミックスイン(またはインターフェイス、または...)はすべて、明確に型の機能を制限する構造であり、あいまいさはありません。彼らはめったに自分のものを所有しません。これにより、2つの変数または2つの関数がないため、型の構成がよりスムーズになります。変数と参照があります。関数と署名。コンパイラは何をすべきかを知っています。
他の一般的なアプローチは、ユーザーにタイプを1つずつ「ビルド」(またはミックス)させることです。基本型が新しい型の同等のパートナーである代わりに、1つの型を別の型に追加します-そこにあるものをすべて上書きします(通常、オーバーライドされたビットの名前を変更および/または再公開するオプションの構文で)。
ミックスイン/トレイトではできないが、C ++スタイルの多重継承では可能なことはありますか?
言語によっては、複数の基本クラスからの変数の関数とストレージの実装をマージし、それらを派生型で公開することが一般的に面倒または不可能になります。
彼らとダイヤモンドの問題に遭遇することは可能ですか?
言語によってはそれほど深刻ではないバリエーションがポップアップ表示される場合がありますが、通常は表示されません。特徴の全体的なポイントは、この種のあいまいさを解消することです。