23

重複の可能性:
C# での多重継承

クラス A とクラス B の 2 つのクラスがあります。これら 2 つのクラスは互いに継承できません。クラス C という新しいクラスを作成しています。今、クラス A とクラス B のメソッドを継承して実装したいと考えています。C# では多重継承ができないことは承知していますが、他にこれを行う方法はありますか?

4

7 に答える 7

52

C#では多重継承はできませんが、インターフェイスを使用してシミュレートできます。C#のシミュレートされた多重継承パターンを参照してください。

B基本的な考え方は、アクセスしたいクラスのメンバーのインターフェースを定義し(それを呼び出しますIB)、次に、のインスタンスを内部に格納することによってC継承Aおよび実装することです。次に例を示します。IBB

class C : A, IB
{
    private B _b = new B();

    // IB members
    public void SomeMethod()
    {
        _b.SomeMethod();
    }
}

そのページで説明されている他のいくつかの代替パターンもあります。

于 2012-06-21T09:07:33.147 に答える
18

継承の一般的な代替手段は委任(コンポジションとも呼ばれます)です。Xは「Y」ではなく「Y」を持っています。したがって、AにFoosを処理する機能があり、BにBarを処理する機能がある場合、両方ともCで、次のようになります。

public class A() {
  private FooManager fooManager = new FooManager(); // (or inject, if you have IoC)

  public void handleFoo(Foo foo) {
    fooManager.handleFoo(foo);
  }
}

public class B() {
  private BarManager barManager = new BarManager(); // (or inject, if you have IoC)

  public void handleBar(Bar bar) {
    barManager.handleBar(bar);
  }
}

public class C() {
  private FooManager fooManager = new FooManager(); // (or inject, if you have IoC)
  private BarManager barManager = new BarManager(); // (or inject, if you have IoC)

  ... etc
}
于 2012-06-21T09:08:22.423 に答える
12

Aからのメソッドコードを文字通り使用したい場合は、クラスにそれぞれのインスタンスを含めるBことができます。Cと のインターフェイスに対してコーディングする場合、クライアントはAやではなくBを与えていることを知る必要はありません。CAB

interface IA { void SomeMethodOnA(); }
interface IB { void SomeMethodOnB(); }
class A : IA { void SomeMethodOnA() { /* do something */ } }
class B : IB { void SomeMethodOnB() { /* do something */ } }
class C : IA, IB
{
    private IA a = new A();
    private IB b = new B();
    void SomeMethodOnA() { a.SomeMethodOnA(); }
    void SomeMethodOnB() { b.SomeMethodOnB(); }
}
于 2012-06-21T09:13:35.463 に答える
9

構成を使用する:

class ClassC
{
    public ClassA A { get; set; }
    public ClassB B { get; set; }   

    public C (ClassA  a, ClassB  b)
    {
        this.A = a;
        this.B = b;
    }
}

次に、を呼び出すことができますC.A.DoA()public InterfaceA Aプロパティを、またはのようなインターフェイスまたは抽象クラスに変更することもできますpublic AbstractClassA A

于 2012-06-21T09:09:29.680 に答える
6

2 つのインターフェイスIAを作成し、次のようにしIBます。

public interface IA
{
    public void methodA(int value);
}

public interface IB
{
    public void methodB(int value);
}

次にA実装IAしてB実装しIBます。

public class A : IA
{
    public int fooA { get; set; }
    public void methodA(int value) { fooA = value; }
}

public class B : IB
{
    public int fooB { get; set; }
    public void methodB(int value) { fooB = value; }
}

次に、次のように C クラスを実装します。

public class C : IA, IB
{
    private A _a;
    private B _b;

    public C(A _a, B _b)
    {
        this._a = _a;
        this._b = _b;
    }

    public void methodA(int value) { _a.methodA(value); }
    public void methodB(int value) { _b.methodB(value); }
}

一般に、これは全体的に貧弱な設計です。なぜなら、と のような同じ名前と変数型を持つメソッドをAと実装することができ、その実装方法を決定する必要があるか、または との両方を呼び出すだけの場合です。他の場所で提案されているように、2 つのクラスを組み合わせるのではなく、とプロパティを検討する必要があります。Bfoo(int bar)foo(bar)_a_b.A.B

于 2012-06-21T09:14:41.010 に答える
3

それらの共通のメソッド/プロパティ/フィールドを保持できる基本クラスを定義できますAB

実装後C:Base

または、多重継承をシミュレートするには、コモンを定義してinterface実装します。C

お役に立てれば。

于 2012-06-21T09:04:21.953 に答える
-4

その場合、クラス C を A & B の基本クラスにしたいということですか。

public abstract class C
{
    public abstract void Method1();

    public abstract void Method2();
}

public class A : C
{
    public override void Method1()
    {
        throw new NotImplementedException();
    }

    public override void Method2()
    {
        throw new NotImplementedException();
    }
}


public class B : C
{
    public override void Method1()
    {
        throw new NotImplementedException();
    }

    public override void Method2()
    {
        throw new NotImplementedException();
    }
}
于 2012-06-21T09:18:48.457 に答える