Für die Benutzeroberfläche wäre das Hinzufügen der abstractoder sogar der publicSchlüsselwörter redundant, sodass Sie sie weglassen:
interface MyInterface {
void Method();
}
In der CIL ist die Methode markiert virtualund 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 Baseund Derivedin derselben Assembly deklariert sind, wird der Compiler Base::Methodvirtuell und versiegelt (in der CIL), obwohl Basedie Schnittstelle nicht implementiert wird.
Wenn Baseund Derivedsich in verschiedenen Assemblys befinden, Derivedändert der Compiler beim Kompilieren der Assembly nicht die andere Assembly, sodass ein Mitglied eingeführt Derivedwird, 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.