W przypadku interfejsu dodanie słów kluczowych abstractlub nawet publicsłów kluczowych byłoby zbędne, więc je pomijasz:
interface MyInterface {
void Method();
}
W CIL metoda jest oznaczona virtuali abstract.
(Należy zauważyć, że Java umożliwia deklarowanie elementów interfejsu public abstract).
W przypadku klasy implementującej istnieje kilka opcji:
Niezastąpiona : w C # klasie nie deklaruje metody jako virtual. Oznacza to, że nie można go przesłonić w klasie pochodnej (tylko ukryty). W CIL metoda jest nadal wirtualna (ale zapieczętowana), ponieważ musi obsługiwać polimorfizm dotyczący typu interfejsu.
class MyClass : MyInterface {
public void Method() {}
}
Zastępowalne : zarówno w C #, jak iw CIL metoda jest virtual. Uczestniczy w wysyłce polimorficznej i może zostać nadpisany.
class MyClass : MyInterface {
public virtual void Method() {}
}
Jawny : w ten sposób klasa może zaimplementować interfejs, ale nie udostępnia metod interfejsu w interfejsie publicznym samej klasy. W CIL metoda będzie private(!), Ale nadal będzie można ją wywołać spoza klasy z odniesienia do odpowiedniego typu interfejsu. Jawne implementacje również nie podlegają zastąpieniu. Jest to możliwe, ponieważ istnieje dyrektywa CIL ( .override), która połączy metodę prywatną z odpowiednią metodą interfejsu, którą implementuje.
[DO#]
class MyClass : MyInterface {
void MyInterface.Method() {}
}
[CIL]
.method private hidebysig newslot virtual final instance void MyInterface.Method() cil managed
{
.override MyInterface::Method
}
W VB.NET można nawet utworzyć alias nazwy metody interfejsu w klasie implementującej.
[VB.NET]
Public Class MyClass
Implements MyInterface
Public Sub AliasedMethod() Implements MyInterface.Method
End Sub
End Class
[CIL]
.method public newslot virtual final instance void AliasedMethod() cil managed
{
.override MyInterface::Method
}
Rozważmy teraz ten dziwny przypadek:
interface MyInterface {
void Method();
}
class Base {
public void Method();
}
class Derived : Base, MyInterface { }
Jeśli Basei Derivedsą zadeklarowane w tym samym zestawie, kompilator utworzy Base::Methodwirtualny i zapieczętowany (w CIL), mimo żeBase nie implementuje interfejsu.
Jeśli Basei Derivedznajdują się w różnych Derivedzestawach , podczas kompilowania zestawu kompilator nie zmieni innego zestawu, więc wprowadzi element członkowski, Derivedktóry będzie jawną implementacją MyInterface::Method, która po prostu deleguje wywołanie do Base::Method.
Jak widać, każda implementacja metody interfejsu musi obsługiwać zachowanie polimorficzne, a zatem musi być oznaczona jako wirtualna w CIL, nawet jeśli kompilator musi przejść przez obręcze, aby to zrobić.