ミックスインまたは特性は、単純な多重継承よりもどのように優れていますか?


54

C ++には単純な多重継承があり、多くの言語設計では危険なものとして禁止されています。しかし、RubyやPHPなどの一部の言語では、奇妙な構文を使用して同じことを行い、それをmixinまたはtraitsと呼びます。ミックスイン/特性は、単純な多重継承よりも悪用しにくいと何度も耳にしました。

それらを特に危険性の低いものにしているのは何ですか?ミックスイン/トレイトではできないが、C ++スタイルの多重継承では可能なことはありますか?彼らとダイヤモンドの問題に遭遇することは可能ですか?

これは、多重継承を使用しているように見えますが、それらを使用できるように、それらがミックスイン/特性であるという言い訳をするだけです。


7
これに対するよく書かれた、思慮深く、徹底的な回答を投稿する人を楽しみにしています。
ロバートハーヴェイ14

7
RubyとPHPは、ミックスインと特性を導入しませんでした。MixinsはFlavors(1980)で導入され、TraitsはSqueak Smalltalk(2001)で導入されました。フレーバーは、多重継承を備えた最初のオブジェクト指向言語であり、ミックスインを使用していました。C ++は、Flavorsの9年後の1989年にリリースされたバージョン2.0でのみ多重継承を取得しました。したがって、質問は次のとおりです。Flavoursには単純なミックスインがありますが、C ++などの一部の言語では、同じことを行い、多重継承と呼ぶ奇妙な構文が導入されています。
ヨルグWミットタグ14

回答:


31

本格的なクラスで使用される場合、多重継承には多くの問題がありますが、それらはすべて曖昧さを中心に展開します。

あいまいさは、いくつかの異なる方法で現れます。

  1. 同じfieldを持つ2つの基本クラスがxあり、派生型がを要求する場合x、何が得られますか?
    • 2つのx変数の型が一致しない場合は、推測できます。
    • それらが同じ型である場合、同じ変数にマージしようとすることができます。
    • あなたは常に奇妙な完全修飾名としてそれらを公開することができます。
  2. f同一のシグネチャを持つ同じ関数を持つ2つの基本クラスがあり、誰かがを呼び出すとf、どちらが呼び出されますか?
    • 2つの基本クラスが別の共通の仮想祖先を共有している場合(ダイヤモンドの問題)。
    • 関数に異なるが互換性のある署名がある場合はどうなりますか?
  3. 2つの基本クラスでクラスを構築するとき、どの基本クラスのコンストラクターが最初に呼び出されますか?殺されたオブジェクトを破壊すると?
  4. オブジェクトをメモリにレイアウトするとき、どのように一貫してそれを行いますか?
  5. これらすべてのケースを3つの基本クラスでどのように処理しますか?10?

また、動的ディスパッチ、型推論、パターンマッチングなど、言語が完全なクラスの多重継承をサポートしている場合により困難になるものについてはあまり知らないことは無視されます。

特性またはミックスイン(またはインターフェイス、または...)はすべて、明確に型の機能を制限する構造であり、あいまいさはありません。彼らはめったに自分のものを所有しません。これにより、2つの変数または2つの関数がないため、型の構成がよりスムーズになります。変数と参照があります。関数と署名。コンパイラは何をすべきかを知っています。

他の一般的なアプローチは、ユーザーにタイプを1つずつ「ビルド」(またはミックス)させることです。基本型が新しい型の同等のパートナーである代わりに、1つの型を別の型に追加します-そこにあるものをすべて上書きします(通常、オーバーライドされたビットの名前を変更および/または再公開するオプションの構文で)。

ミックスイン/トレイトではできないが、C ++スタイルの多重継承では可能なことはありますか?

言語によっては、複数の基本クラスからの変数の関数とストレージの実装をマージし、それらを派生型で公開することが一般的に面倒または不可能になります。

彼らとダイヤモンドの問題に遭遇することは可能ですか?

言語によってはそれほど深刻ではないバリエーションがポップアップ表示される場合がありますが、通常は表示されません。特徴の全体的なポイントは、この種のあいまいさを解消することです。


インスタンスにそのような「構築」タイプを許可する言語/テクノロジーの例を教えてもらえますか?
ガーマン14

@german-私は確かにScalaの専門家ではありませんが、私の理解はwithキーワードがそこで行うことです。
テラスティン14

「明確に型の機能を制限して、あいまいさをなくす構成」:どのような制限がありますか?インターフェースには変数がないため、これは1つの制限ですが、Scalaの特性とRubyモジュールにはあります。他の方法で制限されていますか?
デビッドモールズ

@DavidMoles-これは一般的な方法です。仮想ディスパッチルールにも制限があります(C#の明示的に実装されたインターフェイスを考えてください)。
Telastyn
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.