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