Para la interfaz, la adición de abstract
, o incluso las public
palabras clave sería redundante, por lo que las omite:
interface MyInterface {
void Method();
}
En el CIL, el método está marcado virtual
y abstract
.
(Tenga en cuenta que Java permite declarar miembros de la interfaz public abstract
).
Para la clase de implementación, hay algunas opciones:
No reemplazable : en C #, la clase no declara el método como virtual
. Eso significa que no se puede anular en una clase derivada (solo oculta). En el CIL, el método sigue siendo virtual (pero sellado) porque debe admitir polimorfismo con respecto al tipo de interfaz.
class MyClass : MyInterface {
public void Method() {}
}
Reemplazable : tanto en C # como en CIL, el método es virtual
. Participa en el envío polimórfico y se puede anular.
class MyClass : MyInterface {
public virtual void Method() {}
}
Explícito : esta es una forma para que una clase implemente una interfaz pero no proporcione los métodos de interfaz en la interfaz pública de la clase en sí. En el CIL, el método será private
(!) Pero aún se podrá llamar desde fuera de la clase desde una referencia al tipo de interfaz correspondiente. Las implementaciones explícitas tampoco son reemplazables. Esto es posible porque hay una directiva CIL ( .override
) que vinculará el método privado al método de interfaz correspondiente que está implementando.
[C#]
class MyClass : MyInterface {
void MyInterface.Method() {}
}
[CIL]
.method private hidebysig newslot virtual final instance void MyInterface.Method() cil managed
{
.override MyInterface::Method
}
En VB.NET, incluso puede alias el nombre del método de interfaz en la clase de implementación.
[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
}
Ahora, considere este extraño caso:
interface MyInterface {
void Method();
}
class Base {
public void Method();
}
class Derived : Base, MyInterface { }
Si Base
y Derived
se declaran en el mismo ensamblado, el compilador lo hará Base::Method
virtual y sellado (en el CIL), aunque Base
no implemente la interfaz.
Si Base
y Derived
están en diferentes ensamblados, al compilar el Derived
ensamblado, el compilador no cambiará el otro ensamblado, por lo que introducirá un miembro Derived
que será una implementación explícita para MyInterface::Method
que solo delegará la llamada a Base::Method
.
Como puede ver, cada implementación de método de interfaz debe admitir un comportamiento polimórfico y, por lo tanto, debe marcarse como virtual en el CIL, incluso si el compilador debe pasar por aros para hacerlo.