-2

さて、C# で複数の継承を回避する方法は、インターフェイスを使用することです。これは公平な解決策ですが、クラス間で実際に変更する必要のないインターフェイス内のメソッドを常に再入力する必要があります。

たとえば、インターフェイス Adabo の一部としてメソッド .foo() があり、常に同じことを実行することがわかっている場合 (たとえば、10 回ループする)、開発のある時点で、作成する必要があることがわかります。それに変更を加えると (たとえば、実際には 11 回ループするはずです)、Adabo から継承する各クラスを調べて、それに応じて独自の .foo() を変更する必要があります。

率直に言って、インターフェースで私が望む唯一のことは、多重継承でのフリーパスです。私は彼らのすべてが抽象的な前提にはあまり興味がありません。これを回避する方法はありますか?

4

4 に答える 4

3

文脈がなければ、これは答えるのが難しい質問です。状況に応じて、他のソリューションよりも適切なソリューションが異なります。

まず、他の場所で述べたように、インターフェイスは実装を指定せず、コントラクトのみを指定します。実装は、いくつかの基本クラスに含まれます。クラスは多くのインターフェースを実装できますが、あなたが持っている本当の質問 (私は信じています) は次のとおりです。「複数の継承が不可能な場合、コードの重複を制限しながら、C# クラスに多くのインターフェイスを実装するにはどうすればよいですか?」

多くのオプションがあり、コンテキストが重要です。ただし、さらに調査できるいくつかの一般原則。

  • オブジェクト構成; 他のいくつかのクラスで構成される 1 つのクラスを持つ。たとえば、class carクラスは複数のホイール、エンジン、ドアなどで構成できます。ホイール クラスは、class Bus
  • 横断的関心事/アスペクト指向プログラミング; 具体的な概念ではなく、特定の動作を複製したい場合に適しています。標準的な例は、トレース/ロギングです。ロギング呼び出しをどこでも複製することなく、すべてのメソッドをログに記録する必要があります。PostSharpなど、C# でこれをサポートする優れたツールがありますが、このアプローチには、「従来の」OO 設計とは異なる設計思想が必要です。
  • 拡張方法; これは、型を実際に変更せずに型の動作を実装する場合に非常に便利な .NET 構造です。ここでの最良の例は LINQ です。のすべての実装では、IEnumerable実際に直接何も実装しなくても LINQ メソッドを使用できます。

先に述べたように、コンテキストは重要であり、それがなければ、これらはさらなる調査に役立つ可能性のある一般的な指針にすぎません.

于 2013-01-26T03:09:57.327 に答える
1

C# で複数の継承を回避する方法は、インターフェイスを使用することです

違います。クラスはインターフェースを実装しますが、それらから継承しません。C# (またはその他のマネージ言語) で多重継承を実装する方法はありません。

多重継承に近づく1 つの方法は、集約を使用することです。関数呼び出しをサブパーツに戻すだけの「ラッパー」を作成します。

インターフェース Adabo の一部としてメソッド .foo() があり、常に同じことを行うことがわかっている場合 (たとえば、10 回ループする)

インターフェイスは何もしません具象クラスによって実装する必要があるメソッド/プロパティを定義するだけです。

あなたの質問が単なる理論的なものではない場合は、多重継承が価値があると考える場所の例をいくつか投稿することをお勧めします. あなたが望むものをあなたに与える別のパターンがあるかもしれません.

于 2013-01-26T03:00:12.957 に答える
1

クラス間で実際に変更する必要のないインターフェース内のメソッドを常に再入力する必要があります

全くない。基本クラスにインターフェイスを実装し、インターフェイスを実装するすべてのクラスに共通のメソッドを実装し、残りをabstract - として宣言するだけで、派生物にそれを実装させることができます。

public interface MyInterface
{
    void SomeCommonMethod(object whatever);

    void SomeSpecialisedMethod(int someOtherParameter);
}

public abstract class MyBaseClass : MyInterface
{
    public void SomeCommonMethod(object whatever)
    {
        //do some stuff
    }

    public abstract void SomeSpecialisedMethod(int someOtherParameter);
}

public class SomeSpecialisedClass : MyBaseClass
{
    public override void SomeSpecialisedMethod(int someOtherParameter)
    {
        //do stuff that can't be done in the base class
    }
}

これは、それを必要とするすべてのクラスでインターフェース実装を際限な​​く「再型付け」する必要を回避する方法を示しています。

そうは言っても、インターフェースを使用することは、多重継承と同じではありません。C# の初期には、これについて多くの議論がありました。一般的なコンセンサスは、現実の状況では多重継承の必要性は実際にはほとんどないということでした。個人的には、私のキャリアの中で実際にそれが必要になったのは数回だけであり、それらの場合には適切な回避策がありました.多重継承は単純にクリーンなアプローチでした.

私がインターフェイスに望む唯一のものは、多重継承でのフリーパスです

繰り返し   ますが、インターフェイス内にも多重継承はありません。

1 つのインターフェイスは、他のいくつかのインターフェイスを実装し、独自の要件 (コントラクト) を定義することもできますが、決して継承ではありません。多重継承を近似することはできますが、適切な多重継承を実現することはできません。

于 2013-01-26T03:07:21.527 に答える
1

いろいろごちゃまぜになって混乱してしまったようです。私があなたを正しく理解していれば、インターフェース、たとえば foo() というメソッドを持つ Adabo があります。これで、このメソッドを実装する多くのクラスができました。あなたが書いたことから、このメソッドの実装はこれらすべてのクラスで同じであることがわかります。したがって、実装を変更したい場合は、それらすべてを変更する必要があるということです。

さて、ここにあなたの問題があります。インターフェースのメソッドは、異なる実装クラスが独自のニーズに応じて異なる方法で実装する場合のためのものです。実装がすべて同じである必要がある場合。次に、いくつかの選択肢があります。

  1. 継承: 具象クラスまたは抽象クラスを介して。共通メソッドを親クラスに配置し、それを拡張します。子クラスがすでに他のクラスを拡張していると言っている場合。次に、あなたの次の賭けは、

  2. 構成: 一般的な機能をコンポーネント クラスに配置し、それを使用する必要がある他のクラスに含めます。したがって、インターフェイス Adabo の代わりに、クラス Adabo を使用します。

    クラスアダボ{

    foo();
    

    }

次に、すべての子クラスに

class childA {

   Adabo a;

   ...
   a.foo();
}

class childB {

   Adabo a;

   ...
   a.foo();
}

class childC {

   Adabo a;

   ...
   a.foo();
}
于 2013-01-26T03:47:24.737 に答える