2010-07-11 42 views
8

Tôi có một giao diện để người viết lớp bị buộc phải triển khai một số phương thức nhất định. Tôi cũng muốn cho phép một số phương thức thực hiện mặc định để tôi tạo một lớp trừu tượng. Vấn đề là tất cả các lớp kế thừa từ lớp cơ sở vì vậy tôi có một số hàm trợ giúp trong đó.lớp trừu tượng không thực hiện giao diện

Tôi đã cố gắng viết: IClass với cơ sở trừu tượng nhưng tôi gặp lỗi rằng cơ sở không triển khai Giao diện. Tất nhiên là vì tôi muốn tóm tắt này và để người dùng thực hiện những phương pháp đó. Là một đối tượng trả về nếu tôi sử dụng cơ sở, tôi không thể gọi các phương thức lớp giao diện. Nếu tôi sử dụng giao diện, tôi không thể truy cập các phương thức cơ sở.

Tôi làm cách nào để tạo các lớp trợ giúp này và buộc người dùng triển khai các phương pháp nhất định?

Trả lời

6

Di chuyển các phương thức giao diện vào lớp trừu tượng và khai báo chúng trừu tượng. Bằng cách này, bắt nguồn từ các lớp học buộc phải thực hiện chúng. Nếu bạn muốn hành vi mặc định, sử dụng các lớp trừu tượng, nếu bạn muốn chỉ có chữ ký cố định, sử dụng một giao diện. Cả hai khái niệm đều không pha trộn.

15

Đảm bảo các phương thức trong lớp cơ sở có cùng tên với giao diện và chúng được công khai. Ngoài ra, làm cho chúng ảo để các lớp con có thể ghi đè chúng mà không ẩn chúng.

interface IInterface { 
    void Do(); 
    void Go(); 
} 

abstract class ClassBase : IInterface { 

    public virtual void Do() { 
     // Default behaviour 
    } 

    public abstract void Go(); // No default behaviour 

} 

class ConcreteClass : ClassBase { 

    public override void Do() { 
     // Specialised behaviour 
    } 

    public override void Go() { 
     // ... 
    } 

} 
0

Gặp phải vấn đề tương tự gần đây, tôi đã nghĩ ra một giải pháp khá thanh lịch hơn. Dường như:

public interface IInterface 
{ 
    void CommonMethod(); 
    void SpecificMethod(); 
} 

public abstract class CommonImpl 
{ 
    public void CommonMethod() // note: it isn't even virtual here! 
    { 
     Console.WriteLine("CommonImpl.CommonMethod()"); 
    } 
} 

public class Concrete : CommonImpl, IInterface 
{ 
    void SpecificMethod() 
    { 
     Console.WriteLine("Concrete.SpecificMethod()"); 
    } 
} 

Bây giờ, theo C# spec (. 13.4.4 mapping Interface), trong quá trình lập bản đồ IInterface trên Concrete lớp, trình biên dịch sẽ tìm kiếm cho CommonMethod trong CommonImpl quá, và nó doesn' t thậm chí phải là ảo trong lớp cơ sở!

Ưu điểm quan trọng khác, so với giải pháp của Mau, là bạn không phải liệt kê mọi thành viên giao diện trong lớp cơ sở trừu tượng.

+0

Tôi thích giải pháp của Mau. Đó là rõ ràng và làm cho trình biên dịch làm việc phù hợp cho bạn. Trong giải pháp này, bạn có thể quên thêm IInterface vào lớp dẫn xuất. – PlayTank

+0

@PlayTank: ... và sau đó cuối cùng nó sẽ thất bại trên một số chuyển đổi tiềm ẩn, cũng tại thời gian biên dịch. Mặc dù tôi đồng ý giải pháp thiếu một số độ nghiêm ngặt rõ ràng. – vines

Các vấn đề liên quan