W przypadku interfejsu dodanie słów kluczowych abstract
lub nawet public
słów kluczowych byłoby zbędne, więc je pomijasz:
interface MyInterface {
void Method();
}
W CIL metoda jest oznaczona virtual
i 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 Base
i Derived
są zadeklarowane w tym samym zestawie, kompilator utworzy Base::Method
wirtualny i zapieczętowany (w CIL), mimo żeBase
nie implementuje interfejsu.
Jeśli Base
i Derived
znajdują się w różnych Derived
zestawach , podczas kompilowania zestawu kompilator nie zmieni innego zestawu, więc wprowadzi element członkowski, Derived
któ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ć.