Para a interface, a adição de abstract
, ou mesmo as public
palavras - chave seria redundante, então você as omite:
interface MyInterface {
void Method();
}
No CIL, o método é marcado virtual
e abstract
.
(Observe que o Java permite que os membros da interface sejam declarados public abstract
).
Para a classe de implementação, existem algumas opções:
Não substituível : Em C # a classe não declara o método como virtual
. Isso significa que ele não pode ser substituído em uma classe derivada (apenas oculto). No CIL o método ainda é virtual (mas selado) porque deve suportar polimorfismo em relação ao tipo de interface.
class MyClass : MyInterface {
public void Method() {}
}
Substituível : Tanto em C # quanto em CIL o método é virtual
. Ele participa do envio polimórfico e pode ser substituído.
class MyClass : MyInterface {
public virtual void Method() {}
}
Explícito : esta é uma maneira de uma classe implementar uma interface, mas não fornecer os métodos de interface na interface pública da própria classe. No CIL, o método será private
(!), Mas ainda poderá ser chamado de fora da classe a partir de uma referência ao tipo de interface correspondente. Implementações explícitas também não podem ser substituídas. Isso é possível porque há uma diretiva CIL ( .override
) que vinculará o método privado ao método de interface correspondente 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
}
No VB.NET, você pode até mesmo criar um alias para o nome do método da interface na classe de implementação.
[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
}
Agora, considere este caso estranho:
interface MyInterface {
void Method();
}
class Base {
public void Method();
}
class Derived : Base, MyInterface { }
Se Base
e Derived
forem declarados no mesmo assembly, o compilador se tornará Base::Method
virtual e lacrado (no CIL), embora Base
não implemente a interface.
Se Base
e Derived
estiverem em assemblies diferentes, ao compilar o Derived
assembly, o compilador não mudará o outro assembly, portanto, apresentará um membro em Derived
que será uma implementação explícita para MyInterface::Method
que apenas delegue a chamada a Base::Method
.
Como você pode ver, toda implementação de método de interface deve suportar comportamento polimórfico e, portanto, deve ser marcada como virtual no CIL, mesmo que o compilador precise passar por muitos obstáculos para fazê-lo.