对于该接口,添加abstract
甚至public
关键字是多余的,因此可以忽略它们:
interface MyInterface {
void Method();
}
在CIL中,该方法被标记为virtual
和abstract
。
(请注意,Java允许声明接口成员public abstract
)。
对于实现类,有一些选项:
不可覆盖:在C#中,类未将方法声明为virtual
。这意味着它不能在派生类中被覆盖(只能是隐藏的)。在CIL中,该方法仍然是虚拟的(但是封闭的),因为它必须支持有关接口类型的多态性。
class MyClass : MyInterface {
public void Method() {}
}
可重写:在C#和CIL中,方法均为virtual
。它参与多态调度,可以被覆盖。
class MyClass : MyInterface {
public virtual void Method() {}
}
显式的:这是类实现接口的一种方法,但不提供类本身的公共接口中的接口方法。在CIL中,该方法将是private
(!),但仍然可以从类外部通过对相应接口类型的引用进行调用。显式实现也是不可覆盖的。这是可能的,因为有一个CIL指令(.override
)将私有方法链接到它正在实现的相应接口方法。
[C#]
class MyClass : MyInterface {
void MyInterface.Method() {}
}
[CIL]
.method private hidebysig newslot virtual final instance void MyInterface.Method() cil managed
{
.override MyInterface::Method
}
在VB.NET中,您甚至可以在实现类中为接口方法名称加上别名。
[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
}
现在,考虑这种奇怪的情况:
interface MyInterface {
void Method();
}
class Base {
public void Method();
}
class Derived : Base, MyInterface { }
如果Base
和Derived
在同一程序集中声明,则编译器将进行Base::Method
虚拟和密封(在CIL中),即使Base
未实现该接口也是如此。
如果Base
和Derived
在不同的程序集中,则在编译该Derived
程序集时,编译器不会更改其他程序集,因此它将引入一个成员,Derived
该成员将是一个显式实现MyInterface::Method
,只需将调用委派给即可Base::Method
。
因此,您将看到,每个接口方法实现都必须支持多态行为,因此即使编译器必须经过箍才能实现,也必须在CIL上将其标记为虚拟。