Для інтерфейсу додавання ключових слів 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, навіть якщо компілятор повинен пройти обручі, щоб це зробити.