2

クラスが2つの別々のインターフェイスからインターフェイスを実装する場合、それはまったく同じように動作しますか?C#ダイヤモンド継承(インターフェイス実装)

例:上記

public interface IAnimal { /* ... */ } 
public interface IFullAnimal : IAnimal { /* ... */ } 

public interface IBear : IAnimal { /* ... */ } 
public interface IFullBear : IBear, IFullAnimal { /* ... */ } 

// and implementing IFullBear: 
public class FullBear : IFullBear { /* ... */ } 

FullBearIFullAnimalIFullBear通じIBear両方からIAnimalを実装しています。 IFullAnimalIBearの両方はIAnimalの実装に関する情報を提供していないため(言語では許可されていないため)、IAnimal の実装に関する奇妙な動作が導入されますか。 .NETで

+0

何についての 'インタフェースIA {}インターフェイスIB:IA {}インターフェイスIC:IA、IB {} '。これと実装の関係は何でしょうか?あなたは、クラスにメンバーの 'IAnimal'約束があるという複数の約束をしています。 OK。 –

+3

'IFullBear'は何も実装していませんが、それはインタフェースです。 – crashmstr

+0

だから、あなたは言っている: "私を実装するものは、IAnimalを実装しなければならない"ということは、 'IAnimal'で宣言されたメソッド/プロパティの複数の実装に潜在的につながりかねますか? –

答えて

2

いいえ、これは非常に一般的で無害なシナリオです。

public class List<T> : IList<T>, 
         System.Collections.IList, 
         IReadOnlyList<T> 

IList<T>IReadOnlyList<T>明らかIEnumerable<T>を実装し、世界が終了していない両方:System.Collections.Generic名前空間は、同様の「冗長」インターフェイス宣言の偉大な例です。

動作を変更しインターフェース再実装、とこれを混同しないでください:

interface IFoo 
{ 
    void Foo(); 
} 

class Base: IFoo 
{ 
    public void Foo() { Console.WriteLine("Base Foo!"); 
} 

class Derived: Base { } 

class DerivedWithATwist: Base, IFoo //redeclares interface 
{ 
    void IFoo.Foo() { Console.WriteLine("Derived Foo!"); 
} 

そして今、

IFoo foo = new Base(); 
IFoo derived = new Derived(); 
IFoo derivedWithATwist = new DerivedWithATwist(); 

foo.Foo(); //Base Foo! 
derived.Foo(); //Base Foo! 
derivedWithATwist.Foo(); //Derived Foo! 
(derivedWithATwist as Base).Foo(); //Base Foo! !!! 
+0

既存の例とサンプルコードについては、この回答を受け入れてください。ありがとう! –

3

IAIBの両方がIXから継承したクラスの両方を実装する場合、「IAによって継承IX」のメンバーと「IBによって継承IX」のものとの間に作られた区別はありません。そのようなメンバーはすべて、単にIXのメンバーです。さらに、唯一IAを実装するクラスので、IAIBを実装するように宣言されたものに対して、IAIB、及びIXを実装するように宣言されたクラスの区別、IB存在しないであろう、またはその両方は、必ずしもとしてIXを実施しますまあ、そのように宣言されているかどうかに関わらず。

中間層のインターフェイスは継承されたインターフェイスに、同じインターフェイスの他の継承バージョンと区別されるものを追加できないため、インターフェイスの継承の.NETモデルは「菱形の問題」を回避します。 Javaのモデルもダイヤモンドの問題を回避するために使用されていましたが、中間レベルのインターフェイスでデフォルトメソッドを宣言できるようにすることで、Javaの後のバージョンでは致命的なダイヤモンド階層が可能になりました。

関連する問題