Pour l'interface, l'ajout du abstract, voire des publicmots - clés serait redondant, vous les omettez donc:
interface MyInterface {
void Method();
}
Dans le CIL, la méthode est marquée virtualet abstract.
(Notez que Java autorise la déclaration des membres de l'interface public abstract).
Pour la classe d'implémentation, il existe quelques options:
Non substituable : en C #, la classe ne déclare pas la méthode comme virtual. Cela signifie qu'il ne peut pas être remplacé dans une classe dérivée (uniquement masquée). Dans le CIL, la méthode est toujours virtuelle (mais scellée) car elle doit supporter le polymorphisme concernant le type d'interface.
class MyClass : MyInterface {
public void Method() {}
}
Remplaçable : à la fois en C # et en CIL, la méthode est virtual. Il participe à l'envoi polymorphe et peut être remplacé.
class MyClass : MyInterface {
public virtual void Method() {}
}
Explicite : C'est un moyen pour une classe d'implémenter une interface mais de ne pas fournir les méthodes d'interface dans l'interface publique de la classe elle-même. Dans le CIL, la méthode sera private(!) Mais elle sera toujours appelable de l'extérieur de la classe à partir d'une référence au type d'interface correspondant. Les implémentations explicites ne peuvent pas non plus être remplacées. Cela est possible car il existe une directive CIL ( .override) qui liera la méthode privée à la méthode d'interface correspondante qu'elle implémente.
[C #]
class MyClass : MyInterface {
void MyInterface.Method() {}
}
[CIL]
.method private hidebysig newslot virtual final instance void MyInterface.Method() cil managed
{
.override MyInterface::Method
}
Dans VB.NET, vous pouvez même aliaser le nom de la méthode d'interface dans la classe d'implémentation.
[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
}
Maintenant, considérez ce cas étrange:
interface MyInterface {
void Method();
}
class Base {
public void Method();
}
class Derived : Base, MyInterface { }
Si Baseet Derivedsont déclarés dans le même assembly, le compilateur rendra Base::Methodvirtuel et scellé (dans le CIL), même s'il Basen'implémente pas l'interface.
Si Baseet Derivedsont dans des assemblys différents, lors de la compilation de l' Derivedassembly, le compilateur ne changera pas l'autre assembly, il introduira donc un membre dans Derivedqui sera une implémentation explicite car MyInterface::Methodcela déléguera simplement l'appel à Base::Method.
Ainsi, vous voyez, chaque implémentation de méthode d'interface doit prendre en charge le comportement polymorphe, et doit donc être marquée virtuelle sur le CIL, même si le compilateur doit passer par des cercles pour le faire.