9

今日、C# でのインターフェイスの実装は、「Is-A」の関係ではなく、単なる「Can-Do」の関係であると誰かが私に言いました。これは、LSP (Liskov Substitution Principle) に対する私の長年の信念と矛盾します。私は常に、すべての継承は「Is-A」の関係であるべきだと考えています。

したがって、インターフェースの実装は単なる「できること」の関係です。「IHuman」と「IEngineer」というインターフェースがあり、「IHuman」と「IEngineer」を継承するクラス「Programmer」が1つあるとしたら?確かに、「プログラマー」は「IHuman」と「IEngineer」です。

単なる「Can-Do」関係であれば、IHuman として扱う場合と IEngineer として扱う場合で「Programmer」インスタンスの挙動が異なることは期待できないということでしょうか?

4

5 に答える 5

17

私の経験では、「is-a」と「can-do」の関係を考えるのはあまり役に立ちません。あなたは急速に問題に巻き込まれます。基本的に、現実世界と OO の間のインピーダンスの不一致です。現実世界のモデル化について実際に多くの人が話しているとはいえ、基本的に、使用しているプラ​​ットフォームで型間の関係が何を意味するかを理解する必要があります。

インターフェースを機能として使用できる場合もあれば、より通常の「is-a」関係を表す場合もあります。私はそれについてあまり夢中になりません-彼らができることとできないことを理解していることを確認してください.

于 2008-11-01T08:35:36.830 に答える
6

私はインターフェイスを動作の契約と考える傾向があります。IComparable や IEnumerable などのインターフェイスは典型的な例です。

あなたが示した例では、 IHuman と IEngineer は実際には動作ではありません。

于 2008-11-01T08:28:26.593 に答える
4

この質問はかなり遅れて見つかりましたが、私はチャイムを鳴らしたかったのです。

C# のインターフェイスには is-a 関係がありますが、is-an-object ではありません。むしろ、実装です。

つまり、IBar を実装するクラス Foo に対して、次のテストを行います。

Foo myFoo = new Foo(); 
return myFoo is IBar;

文字通り true を返します。次のようにも言えます。

IBar bar = myArrayList[3] as IBar;
Foo foo = bar as Foo;

または、メソッドが IBar を必要とする場合は、Foo を渡すことができます。

void DoSomething(IBar bar) {
}

static void Main() {
    Foo myFoo = new Foo();
    DoSomething(myFoo);
}

明らかに、IBar 自体には実装がないため、can-do 関係も適用されます。

interface IBar { void happy(); }
class Foo : IBar
{
    void happy()
    {
        Console.Write("OH MAN I AM SO HAPPY!");
    }
}
class Program
{
    static void Main()
    {
        IBar myBar = new Foo();
        myBar.happy();
    }
}

しかし、それについては、オブジェクトの継承についても同じことが言えます。クラス Bar を継承するクラス Foo のオブジェクトには、インターフェイスと同じように、is-a 関係だけでなく can-do 関係もあります。その実装が事前に構築されているだけです。

本当の問題は、is-a- what、can-do- what ? です。継承されたクラス オブジェクトは[親インスタンス]であり、can-do- [親の動作]であるのに対し、インターフェイスの実装は[インターフェイスの実装]であり、したがって can-do- [インターフェイスの動作]です。

上記のようなプログラムによる is-a 関係が使用されるほとんどの場合、インターフェースのみが評価されるため、継承されたクラスと実装されたインターフェースの両方が同じ is-a と can-do の性質を共有します。

HTH、ジョン

于 2009-01-07T21:11:37.470 に答える
2

.NET フレームワークの設計者は、インターフェイスを使用して "has a" (または "can do") 関係を指定しますが、"is a" は継承を使用して実装されます。

この理由は、.NET Framework 開発者ガイドの「クラスとインターフェイスの選択」セクションに記載されています。

インターフェイスは、実装者が提供する必要がある一連のメンバーの署名を定義します。インターフェイスは、メンバーの実装の詳細を提供できません。

したがって、"Programmer" および "Engineer" のサンプル クラスは、独自の特定の機能を備えている可能性が高いため、継承を使用してより適切に実装できます。

于 2008-11-01T08:37:06.733 に答える
2

実際には、ほとんどのインターフェースが名前ではなく機能であるため、

IComparable、ITestable、IEnumerable

人間、動物、犬など

とにかく、すでに述べたように、実用的である必要がありますが、私がコーディングするときの一般的なルールがあります:概念、慣習、または標準的な慣行が仕事を成し遂げるための邪魔にならないようにしてください。学術よりも実用的である方がよい.

したがって、インターフェイスが本当に自分の設計により適していると確信している場合は、それを選択してください。このような質問について心配する必要はありません。

于 2008-11-01T17:17:43.187 に答える