重複の可能性:
C# での多重継承
クラス A とクラス B の 2 つのクラスがあります。これら 2 つのクラスは互いに継承できません。クラス C という新しいクラスを作成しています。今、クラス A とクラス B のメソッドを継承して実装したいと考えています。C# では多重継承ができないことは承知していますが、他にこれを行う方法はありますか?
C#では多重継承はできませんが、インターフェイスを使用してシミュレートできます。C#のシミュレートされた多重継承パターンを参照してください。
B基本的な考え方は、アクセスしたいクラスのメンバーのインターフェースを定義し(それを呼び出しますIB)、次に、のインスタンスを内部に格納することによってC継承Aおよび実装することです。次に例を示します。IBB
class C : A, IB
{
private B _b = new B();
// IB members
public void SomeMethod()
{
_b.SomeMethod();
}
}
そのページで説明されている他のいくつかの代替パターンもあります。
継承の一般的な代替手段は委任(コンポジションとも呼ばれます)です。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
}
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(); }
}
構成を使用する:
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。
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
それらの共通のメソッド/プロパティ/フィールドを保持できる基本クラスを定義できますA。B
実装後C:Base。
または、多重継承をシミュレートするには、コモンを定義してinterface実装します。C
お役に立てれば。
その場合、クラス 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();
}
}