Pour l'interface, l'ajout du abstract
, voire des public
mots - clés serait redondant, vous les omettez donc:
interface MyInterface {
void Method();
}
Dans le CIL, la méthode est marquée virtual
et 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 Base
et Derived
sont déclarés dans le même assembly, le compilateur rendra Base::Method
virtuel et scellé (dans le CIL), même s'il Base
n'implémente pas l'interface.
Si Base
et Derived
sont dans des assemblys différents, lors de la compilation de l' Derived
assembly, le compilateur ne changera pas l'autre assembly, il introduira donc un membre dans Derived
qui sera une implémentation explicite car MyInterface::Method
cela 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.