方法は、デフォルトでは仮想ないです。インタフェース定義で定義されているコントラクトの実装を提供しているだけです。メソッドをvirtual
とマークすることで、派生クラスが定義されているコントラクトを引き続き尊重しながら、追加または個別の実装を提供できるようになります。
interface IAnimal
{
string Speak();
}
class Dog : IAnimal
{
public string Speak()
{
return "Bark!";
}
}
Dog
クラスである契約IAnimal
の実装を提供することによって、インタフェースを実装:
この例を考えます。ここには仮想メソッドはなく、オーバーライドもありません。
は今、この例を考えてみます。
interface IAnimal
{
string Speak();
}
class Dog : IAnimal
{
public virtual string Speak()
{
return "Bark!";
}
}
class GoldenRetriever : Dog
{
public override string Speak()
{
return "I am a golden retriever who says "
+ base.Speak();
}
}
は今Dog
クラスは、派生クラスの追加や、新たな実装を提供することを可能にするvirtual
するSpeak
を宣言しました。 Speak
メソッドへの呼び出しがまだ文字列を返すので、これはIAnimal
との契約を中断しません。
いいえ、最後の例です。インターフェイスは実装を必要とせず、契約が満たされていることのみを要求します。つまり、インタフェースは、実装クラス内に一致するシグネチャを持つメンバーが存在することのみを認識します。これは、我々はまた、この操作を行うことができることを意味します
interface IAnimal
{
string Speak();
}
abstract class Dog : IAnimal
{
public abstract string Speak();
}
class GoldenRetriever : Dog
{
public override string Speak()
{
return "I am a golden retriever";
}
}
お知らせ今Dog
クラスは全くSpeak
のための実装を提供しないことを、まだ契約の要件を満たしています。
インターフェイスもクラスからクラスに継承されるため、上記のすべての例ではDog
とGoldenRetriever
の両方がIAnimal
インターフェイスを実装しています。いずれのクラスもSpeak
メソッドを非表示にします。両方のクラスはを実装しています。
私はあなたの混乱は、仮想メソッドがクラスではなくインターフェースで定義されているという事実から来ていると思います。ここで私は上記で定義されたインタフェースのためのILは、次のとおりです。
.class private interface abstract auto ansi IAnimal
{
.method public hidebysig newslot abstract
virtual instance string Speak() cil managed
{
}
}
あなたがここにも種類がinterface
に指定されていることに気づく必要があるvirtual
などの方法が定義されていることが正しいですが。これは純粋にマイクロソフトのC#コンパイラによって生成されたMSILの実装の詳細です。別のコンパイラでも意味的に同じ結果が得られれば、別のコードを簡単に生成できます。
ここで重要なのは、メソッドがvirtual
としてインターフェイスに宣言されていても、クラスで宣言されたvirtual
メソッドと同じことを意味するものではありません。
仮想の代わりに、インターフェイスのメソッドがデフォルトでは抽象であるとすると、理にかなっています。 –
はい、いいですが、コンパイラが仮想メソッドにアタッチすると、メソッドを実装している間に再び仮想メソッドを実装すると、コンパイラは元の宣言を隠していると言います。 –