Für die Benutzeroberfläche wäre das Hinzufügen der abstract
oder sogar der public
Schlüsselwörter redundant, sodass Sie sie weglassen:
interface MyInterface {
void Method();
}
In der CIL ist die Methode markiert virtual
und abstract
.
(Beachten Sie, dass mit Java Schnittstellenmitglieder deklariert werden können. public abstract
)
Für die implementierende Klasse gibt es einige Optionen:
Nicht überschreibbar : In C # deklariert die Klasse die Methode nicht als virtual
. Das bedeutet, dass es in einer abgeleiteten Klasse nicht überschrieben werden kann (nur versteckt). In der CIL ist die Methode immer noch virtuell (aber versiegelt), da sie den Polymorphismus hinsichtlich des Schnittstellentyps unterstützen muss.
class MyClass : MyInterface {
public void Method() {}
}
Overridable : Sowohl in C # als auch in CIL ist die Methode virtual
. Es nimmt am polymorphen Versand teil und kann überschrieben werden.
class MyClass : MyInterface {
public virtual void Method() {}
}
Explizit : Dies ist eine Möglichkeit für eine Klasse, eine Schnittstelle zu implementieren, jedoch nicht die Schnittstellenmethoden in der öffentlichen Schnittstelle der Klasse selbst bereitzustellen. In der CIL ist die Methode private
(!), Kann jedoch weiterhin von außerhalb der Klasse über einen Verweis auf den entsprechenden Schnittstellentyp aufgerufen werden. Explizite Implementierungen können ebenfalls nicht überschrieben werden. Dies ist möglich, weil es eine CIL-Direktive ( .override
) gibt, die die private Methode mit der entsprechenden Schnittstellenmethode verknüpft, die sie implementiert.
[C #]
class MyClass : MyInterface {
void MyInterface.Method() {}
}
[CIL]
.method private hidebysig newslot virtual final instance void MyInterface.Method() cil managed
{
.override MyInterface::Method
}
In VB.NET können Sie sogar den Namen der Schnittstellenmethode in der implementierenden Klasse als Alias verwenden.
[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
}
Betrachten Sie nun diesen seltsamen Fall:
interface MyInterface {
void Method();
}
class Base {
public void Method();
}
class Derived : Base, MyInterface { }
Wenn Base
und Derived
in derselben Assembly deklariert sind, wird der Compiler Base::Method
virtuell und versiegelt (in der CIL), obwohl Base
die Schnittstelle nicht implementiert wird.
Wenn Base
und Derived
sich in verschiedenen Assemblys befinden, Derived
ändert der Compiler beim Kompilieren der Assembly nicht die andere Assembly, sodass ein Mitglied eingeführt Derived
wird, das eine explizite Implementierung darstellt MyInterface::Method
, an die der Aufruf lediglich delegiert wird Base::Method
.
Sie sehen also, jede Implementierung der Schnittstellenmethode muss polymorphes Verhalten unterstützen und daher in der CIL als virtuell markiert sein, selbst wenn der Compiler dafür Hoops durchlaufen muss.