Đối với giao diện, việc bổ sung abstract
hoặc thậm chí các public
từ khóa sẽ là thừa, vì vậy bạn bỏ qua chúng:
interface MyInterface {
void Method();
}
Trong CIL, phương thức được đánh dấu virtual
và abstract
.
(Lưu ý rằng Java cho phép khai báo các thành viên giao diện public abstract
).
Đối với lớp triển khai, có một số tùy chọn:
Không thể ghi đè : Trong C #, lớp không khai báo phương thức là virtual
. Điều đó có nghĩa là nó không thể bị ghi đè trong một lớp dẫn xuất (chỉ ẩn). Trong CIL, phương thức vẫn là ảo (nhưng được niêm phong) vì nó phải hỗ trợ tính đa hình liên quan đến kiểu giao diện.
class MyClass : MyInterface {
public void Method() {}
}
Có thể ghi đè : Cả trong C # và trong CIL, phương thức này là virtual
. Nó tham gia vào công văn đa hình và nó có thể bị ghi đè.
class MyClass : MyInterface {
public virtual void Method() {}
}
Rõ ràng : Đây là cách để một lớp triển khai một giao diện nhưng không cung cấp các phương thức giao diện trong giao diện chung của chính lớp đó. Trong CIL, phương thức sẽ là private
(!) Nhưng nó vẫn có thể được gọi từ bên ngoài lớp từ một tham chiếu đến kiểu giao diện tương ứng. Các triển khai rõ ràng cũng không thể ghi đè. Điều này có thể thực hiện được vì có một chỉ thị CIL ( .override
) sẽ liên kết phương thức private với phương thức giao diện tương ứng mà nó đang triển khai.
[C #]
class MyClass : MyInterface {
void MyInterface.Method() {}
}
[CIL]
.method private hidebysig newslot virtual final instance void MyInterface.Method() cil managed
{
.override MyInterface::Method
}
Trong VB.NET, bạn thậm chí có thể đặt bí danh cho tên phương thức giao diện trong lớp thực thi.
[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
}
Bây giờ, hãy xem xét trường hợp kỳ lạ này:
interface MyInterface {
void Method();
}
class Base {
public void Method();
}
class Derived : Base, MyInterface { }
Nếu Base
và Derived
được khai báo trong cùng một assembly, trình biên dịch sẽ tạo Base::Method
ảo và được niêm phong (trong CIL), mặc dùBase
không triển khai giao diện.
Nếu Base
và Derived
nằm trong các assembly khác nhau, khi biên dịch Derived
assembly, trình biên dịch sẽ không thay đổi assembly khác, vì vậy nó sẽ giới thiệu một thành viên trong Derived
đó sẽ là một triển khai rõ ràng cho MyInterface::Method
điều đó sẽ chỉ ủy quyền cuộc gọi đến Base::Method
.
Vì vậy, bạn thấy, mọi triển khai phương thức giao diện phải hỗ trợ hành vi đa hình và do đó phải được đánh dấu ảo trên CIL, ngay cả khi trình biên dịch phải trải qua vòng lặp để thực hiện điều đó.