45

The C# Programming Languageでは、Krzysztof Cwalina が注釈で次のように述べています。

多重継承のサポートを追加しないことを明示的に決定しました [...] 多重継承の欠如により、インターフェイスの概念を追加せざるを得なくなりました。これは、フレームワークの進化、より深い継承階層、およびその他多くの問題の原因となっています。問題。

インターフェースは、OO プログラミング言語の中核となる概念です。「インターフェースの概念を強制的に追加する」という意味には従いません

Krzysztof は、複数の継承が使用されるインターフェイスの使用に関して、特定の設計上の決定を行う必要があったことを意味しますか? それとも、interface多重継承がないために が C# に導入されたということですか? 例を挙げていただけますか?

4

4 に答える 4

25

インターフェイスは、データ メンバーを持たず、public abstractメソッドのみを定義する単純な基本クラスです。たとえば、これは C++ のインターフェイスになります。

class IFrobbable {
    public:
    virtual void Frob() = 0;
}

したがって、MI が言語機能として利用できる場合は、インターフェイスを単に派生させるだけでインターフェイスを「実装」できます (ここでも C++)。

class Widget : public IFrobbable, public IBrappable {
    // ...
}

一般的なケースでの多重継承は、多くの疑問や問題を引き起こします。これらの疑問や問題は、必ずしも 1 つの答えを持っているわけではありません。また、「良い」という特定の定義に適した答えを持っているとは限りません (恐ろしいひし形、誰か?)。インターフェイスを「継承」するという概念は、本格的なクラスを継承する非常に制約のある特殊なケースであるため、複数のインターフェイスの実装はこれらの問題のほとんどを回避します。

そして、ここで「インターフェースの概念を追加することを余儀なくされました」の出番です。たとえば、コードの再利用が実際には 1 つである場合、コードを再利用できないという深刻な問題があります。オブジェクト指向の最も一般的な引数の。さらに何かをしなければなりません。次のステップは多重継承を追加することですが、インターフェースの制約を満たすクラスに対してのみです。

だから、私はクシシュトフの引用を次のように解釈します

一般に、多重継承は非常に厄介な問題であり、.NET の開発における実際の制約を考えると、満足のいく方法で取り組むことができませんでした。ただし、インターフェイスの継承は、取り組むのがはるかに簡単であり、OOP で非常に重要であるため、それを組み込みました。もちろん、インターフェイスには、主に BCL の構造に関する一連の問題があります。

于 2013-01-23T15:06:41.613 に答える
11

クリス・ブルメより:

複数の実装の継承を直接実装しない理由はいくつかあります。(ご存知のように、複数のインターフェイスの継承をサポートしています)。

クシシュトフ・ツワリナが引用で述べているのは、インターフェースの概念自体ではなく、多重継承の方法としての多重インターフェース継承だと思います。

複数の実装継承の、組み込みの検証可能な CLS 準拠バージョンを提供していない理由はいくつかあります。

  1. MI がどのように機能するかについて、実際には言語が異なれば期待も異なります。たとえば、競合がどのように解決されるか、重複したベースがマージされるか冗長になるかなどです。CLR に MI を実装する前に、すべての言語を調査し、共通の概念を見つけ出し、それらを言語に依存しない方法で表現する方法を決定する必要があります。また、MI が CLS に属するかどうか、およびこの概念を必要としない言語 (おそらく VB.NET など) にとってこれが何を意味するかを決定する必要があります。もちろん、これは共通言語ランタイムとして私たちが取り組んでいるビジネスですが、MI でそれを行うにはまだ手がかりがありません。

  2. MI が真に適切な場所は、実際には非常に少ないです。多くの場合、代わりに複数のインターフェイスの継承を使用して作業を完了できます。それ以外の場合は、カプセル化と委任を使用できる場合があります。ミックスインのような少し異なる構造を追加すると、実際にはより強力になるでしょうか?

  3. 複数の実装の継承により、実装が非常に複雑になります。この複雑さは、キャスト、レイアウト、ディスパッチ、フィールド アクセス、シリアライゼーション、ID 比較、検証可能性、リフレクション、ジェネリック、およびおそらく他の多くの場所に影響を与えます。

于 2013-01-23T14:55:41.263 に答える
5

エリック・リッパートが言っていることを読むInterfacesべきだと思います。彼は手を汚しているので、他の誰よりもよく知っていると思います。

場合によっては最悪のケースと最悪のケースがあります。悪くない方を選ばなければなりません。

以下は、リンクされた投稿のコピーです。


それらは、(インターフェース内の) 上記の関数が継承クラスに実装されていることを確認するためだけに存在します。

正しい。これは、この機能を正当化するのに十分なメリットです。他の人が言ったように、インターフェイスは、特定のメソッド、プロパティ、およびイベントを実装する契約上の義務です。静的に型付けされた言語の魅力的な利点は、コードが依存するコントラクトが実際に満たされていることをコンパイラが検証できることです。

とはいえ、インターフェースは契約上の義務を表すにはかなり弱い方法です。契約上の義務をより強力かつ柔軟に表す方法が必要な場合は、Visual Studio の最新バージョンに同梱されている Code Contracts 機能を調べてください。

C# は優れた言語ですが、最初に Microsoft が問題を作成 (多重継承を許可しない) してから解決策を提供するように感じることがありますが、これはかなり面倒です。

気に入っていただけてうれしいです。

すべての複雑なソフトウェア設計は、競合する機能を互いに比較検討し、小さなコストで大きな利益をもたらす「スイート スポット」を見つけようとする結果です。実装を共有する目的で多重継承を許可する言語は、メリットが比較的小さく、コストが比較的大きいということを、私たちはつらい経験から学びました。実装の詳細を共有しないインターフェイスでのみ多重継承を許可すると、ほとんどのコストなしで多重継承の多くの利点が得られます。

于 2013-01-23T15:03:15.683 に答える
2

Cwalina の言葉はやや強く、歴史に関して完全に正確ではないと思います。

インターフェースは C# よりも前に存在していたことを思い出してください。「問題 x を解決するためにインターフェースを追加する必要があった」と言うのは、私には正しく聞こえません。インターフェイスはデフォルトでそこにあると思います-そうでなければならなかったでしょう。

また、C# は主に C++ から派生していることにも注意してください。または、少なくとも、C# 言語の作成に携わった人々は、C++ に非常に強いバックグラウンドを持っていたはずです。多重継承は、C++ の悪夢の領域として認識されていました。共通の基本クラスから派生する可能性のある複数のクラスから継承し、どの実装が優先されるかを調べます。つまり、これは非常に強力な機能ですが、間違いなく複雑なコードになる可能性があります。

彼ら (言語の作成者) はすべてが複雑になる可能性があることを知っており、それを避けたかったため、C# から複数の継承を削除したのではないかと思います。また、C# が導入されたときのセールス ポイントの 1 つはそのクリーンさ (Java ほどクリーンではありませんが、C および C++ よりもはるかにクリーンです) であったことも覚えておいてください。

ちなみに、10 年以上の C# 開発の中で、多重継承を望んだのは 1 回だけです。ビジュアル スタイルといくつかの一般的な動作の両方を継承したい UI コンポーネント。いずれにせよ、私が意図していたことがかなりひどいデザインになることに気付くのに、それほど時間はかかりませんでした。

于 2013-01-24T12:52:33.063 に答える