web-dev-qa-db-ja.com

C#は多重継承をサポートしていますか?

同僚と私は、多重継承について少し議論しています。私はそれがサポートされていないと言っています、そして彼はそうだと言っています。だから、私はネット上でbrain明な束を尋ねると思いました。

55
Neil Knight

いいえ、代わりにインターフェイスを使用してください! ^。^

43
Barrie Reader

申し訳ありませんが、_multiple classes_から継承することはできません。インターフェイスまたはone class and interface(s)の組み合わせを使用できます。ここで、インターフェイスの後に署名内のクラス名が続く必要があります。

_interface A { }
interface B { }
class Base { }
class AnotherClass { }
_

継承する可能な方法:

_class SomeClass : A, B { } // from multiple Interface(s)
class SomeClass : Base, B { } // from one Class and Interface(s)
_

これは違法です:

_class SomeClass : Base, AnotherClass { }
_
86
Asad Butt

C#では多重継承はサポートされていません。

ただし、2つのソースから動作を「継承」する場合は、次の組み合わせを使用しないでください。

  • 構成
  • 依存性注入

基本的だが重要なOOP原則は、「継承よりも合成を優先する」というものです。

次のようなクラスを作成できます。

public class MySuperClass
{
    private IDependencyClass1 mDependency1;
    private IDependencyClass2 mDependency2;

    public MySuperClass(IDependencyClass1 dep1, IDependencyClass2 dep2)
    {
        mDependency1 = dep1;
        mDependency2 = dep2;
    }

    private void MySuperMethodThatDoesSomethingComplex()
    {
        string s = mDependency1.GetMessage();
        mDependency2.PrintMessage(s);
    }
}

ご覧のとおり、依存関係(インターフェイスの実際の実装)はコンストラクターを介して注入されます。あなたのクラスは、各クラスがどのように実装されているかを知りませんが、それらを使用する方法を知っています。したがって、ここに含まれるクラス間の疎結合ですが、使用力は同じです。

今日の傾向は、相続が一種の「時代遅れ」であることを示しています。

20
Liviu M.

C#3.5以下では多重継承をサポートしていませんが、C#4.0では、覚えているようにDynamicsを使用してこれを行うことができます。

13
Gnought

3.5までC#で多重継承を行うことはできません。私はそれを見ていないので、4.0でどのように機能するかわかりませんが、@ tbischelは私が読む必要があるリンクを投稿しました。

C#を使用すると、「複数の継承」とはまったく異なるインターフェイスを介して「複数の実装」を実行できます。

そのため、次のことはできません。

class A{}

class B{}

class C : A, B{}

ただし、次のことができます。

interface IA{}
interface IB{}

class C : IA, IB{}

HTH

7
Sunny

C#はクラスの多重継承をサポートしていませんが、任意の数のインターフェースを継承/実装することが許可されています。

これは違法です(B、C、D、Eはすべてのクラスです)

class A : B, C, D, E
{
}

これは正当です(IB、IC、ID&IEはすべてのインターフェースです)

class A : IB, IC, ID, IE
{
}

これは合法です(Bはクラス、IC、IDですIEはインターフェイスです)

class A : B, IC, ID, IE
{
}

継承に対する構成 は、多重継承をサポートする言語でも好ましいと思われる設計パターンです。

6
series0ne

Java(C#が間接的に派生したもの))と同様に、C#は多重継承をサポートしていません。

つまり、クラスdata(メンバー変数とプロパティ)は、単一の親ベースclassからのみ継承できます。一方、クラスbehavior(メンバーメソッド)は、複数の親ベースから継承できますinterfaces

一部の専門家、特に Bertrand Meyer (オブジェクト指向プログラミングの父の1人と考えられている人もいます)は、これによってC#(およびJava、その他すべて)が「真」であることを認めないと考えています。オブジェクト指向言語。

4
David R Tribble

実際には、継承の定義に依存します。

  • 実装(メンバー、つまりデータと動作)をsingleクラスから継承できますが、
  • interfacesmultipleから継承できます。

これは、通常、「継承」という用語が意味するものではありませんが、このように定義することは完全に不合理ではありません。

3
Jörg W Mittag

多重継承により、プログラマは、複数のクラスとそれに対応する階層の側面を組み合わせたクラスを作成できます。例えばC++では、複数のクラスから継承できます。

C#では、クラスは単一の継承と呼ばれる単一の親クラスからのみ継承できます。ただし、インターフェイスを使用することも、1つのクラスとインターフェイスを組み合わせて使用​​することもできます。この場合、インターフェイスではシグネチャのクラス名が後に続きます。

例:

Class FirstClass { }
Class SecondClass { }

interface X { }
interface Y { }

次のように継承できます。

class NewClass:X、Y {}上記のコードでは、クラス「NewClass」は複数のインターフェイスから作成されます。

class NewClass:FirstClass、X {}上記のコードでは、クラス「NewClass」はインターフェースXとクラス「FirstClass」から作成されます。

2
Sandeep Verma

シミュレートされた多重継承パターン
http://www.codeproject.com/KB/architecture/smip.aspx enter image description here

2
Donny V.

一度に複数のクラスを継承することはできません。しかし、インターフェースの助けを借りてそれを行うオプションがあります。以下のコードを参照してください

interface IA
{
    void PrintIA();
}

class  A:IA
{
    public void PrintIA()
    {
        Console.WriteLine("PrintA method in Base Class A");
    }
}

interface IB
{
    void PrintIB();
}

class B : IB
{
    public void PrintIB()
    {
        Console.WriteLine("PrintB method in Base Class B");
    }
}

public class AB: IA, IB
{
    A a = new A();
    B b = new B();

    public void PrintIA()
    {
       a.PrintIA();
    }

    public void PrintIB()
    {
        b.PrintIB();
    }
}

以下のように呼び出すことができます

AB ab = new AB();
ab.PrintIA();
ab.PrintIB();
2
reza.cse08

議論をさらに一歩進めて、デザインパターンについて話をしたいと思うかもしれません。

2
Jason M

通常、あなたはできません

以下のインターフェースとクラスを検討してください。

public class A { }    
public class B { }
public class C { }

public interface IA { }
public interface IB { }

複数のインターフェイスを継承できます。

class A : B, IA, IB {
  // Inherits any single base class, plus multiple interfaces.
}

ただし、複数のクラスを継承することはできません

class A : B, C, IA, IB {
    // Inherits multiple base classes, plus multiple interfaces.
}
1
Elshan

それを許可しません。それを達成するためにインターフェースを使用します。

なぜそうなのですか?

答えは次のとおりです:コンパイラは、継承されたものとどこから継承されたかについて常に一貫性のある非常に合理的かつ合理的な決定を行うことができるため、キャストを行ったときに、どの実装を扱っているかを常に正確に知ることができます。

1
Awais Ahmad

C#は組み込みの多重継承をサポートしていません。

複数の継承をサポートしない言語に追加するには、 twin design pattern を使用できます

1
Mohsen Kashi

提案されたものに対する追加の提案として、多重継承に類似した機能を提供する別の賢い方法は、複数のインターフェースを実装することですが、これらのインターフェースに拡張メソッドを提供します。これは mixins と呼ばれます。これは本当の解決策ではありませんが、多重継承を実行するように促す問題を時々処理します。

0
Jaxidian

私は最近、どういうわけか同じ考え方に到達し、2つのクラスを1つのクラスに継承し、このページに行き着きました(私はよく知っていますが)

この問題に対する私の解決策は、データを意味のあるクラスに分割することです。

public class PersonAddressSuper
{
    public PersonBase Person { get; set; }
    public PersonAddress Address { get; set; }

    public class PersonBase
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
    public class PersonAddress
    {
        public string StreetAddress { get; set; }
        public string City { get; set; }
    }
}

コードの後半で、次のように使用できます。

両方のパーツ、ベースおよびアドレスを含める

PersonAddressSuper PersonSuper = new PersonAddressSuper();
PersonSuper.PersonAddress.StreetAddress = "PigBenis Road 16";

ベースのみ:

PersonAddressSuper.PersonBase PersonBase = new PersonAddressSuper.PersonBase();
PersonBase.Name = "Joe Shmoe";

住所のみ:

PersonAddressSuper.PersonAddress PersonAddress = new PersonAddressSuper.PersonAddress();
PersonAddress.StreetAddress = "PigBenis Road 16";
0
Dementic