2010-05-05 14 views
6

Trong C++, bạn có thể làm như sau:Buộc sử dụng các giao diện thay vì thực hiện cụ thể trong việc kê khai (NET)

class base_class 
{ 
public: 
    virtual void do_something() = 0; 
}; 

class derived_class : public base_class 
{ 
private: 
    virtual void do_something() 
    { 
     std::cout << "do_something() called"; 
    } 
}; 

Các derived_class override phương thức do_something() và làm cho nó private. Hiệu quả là, rằng cách duy nhất để gọi phương pháp này là như thế này:

base_class *object = new derived_class(); 
object->do_something(); 

Nếu bạn khai báo các đối tượng như kiểu derived_class, bạn không thể gọi phương thức vì đó là tin:

derived_class *object = new derived_class(); 
object->do_something(); 
// --> error C2248: '::derived_class::do_something' : cannot access private member declared in class '::derived_class' 

Tôi nghĩ điều này khá hay, bởi vì nếu bạn tạo một lớp trừu tượng được sử dụng như một giao diện, bạn có thể chắc chắn rằng không ai vô tình khai báo một trường là kiểu cụ thể, nhưng luôn sử dụng lớp giao diện.

Vì trong C#/.NET nói chung, bạn không được phép thu hẹp quyền truy cập từ public đến private khi ghi đè phương pháp, có cách nào để đạt được hiệu ứng tương tự ở đây không?

Trả lời

14

Nếu bạn triển khai giao diện một cách rõ ràng, điều này ít nhất sẽ khuyến khích mọi người sử dụng loại giao diện trong khai báo.

interface IMyInterface 
{ 
    void MyMethod(); 
} 

class MyImplementation : IMyInterface 
{ 
    void IMyInterface.MyMethod() 
    { 
    } 
} 

Một sẽ chỉ nhìn thấy MyMethod sau khi đúc các ví dụ để IMyInterface. Nếu khai báo sử dụng kiểu giao diện thì không cần sử dụng trong lần sử dụng tiếp theo.

MSDN page on explicit interface implementation (nhờ Luke, tiết kiệm cho tôi một vài giây ^^)

IMyInterface instance = new MyImplementation(); 
instance.MyMethod(); 

MyImplementation instance2 = new MyImplementation(); 
instance2.MyMethod(); // Won't compile with an explicit implementation 
((IMyInterface)instance2).MyMethod(); 
+0

Hiệu ứng này là những gì tôi muốn, cảm ơn. – gammelgul

+0

+1 Tôi vừa học được điều gì đó mới mẻ! – BritishDeveloper

+0

+1 Cảm ơn vì điều này, cũng đã học được điều gì đó mới mẻ! – Deano

2

Bạn có thể giảm tính khả dụng của phương thức bằng cách đánh dấu nó là new.

Ví dụ từ MSDN's CA2222: Do not decrease inherited member visibility:

using System; 
namespace UsageLibrary 
{ 
    public class ABaseType 
    { 
     public void BasePublicMethod(int argument1) {} 
    } 
    public class ADerivedType:ABaseType 
    { 
     // Violates rule: DoNotDecreaseInheritedMemberVisibility. 
     // The compiler returns an error if this is overridden instead of new. 
     private new void BasePublicMethod(int argument1){}  
    } 
} 

Điều này thực sự thú vị hơn như một bài tập học tập; nếu mã của bạn thực sự phụ thuộc vào việc không thể gọi số BasePublicMethod trên ADerivedType, đó là dấu hiệu cảnh báo về thiết kế không rõ ràng.

4

Bạn có thể làm điều này trong thế giới Net quá, sử dụng explicit interface implementation

Như một ví dụ, BindingList<T> thực hiện IBindingList, nhưng bạn phải bỏ nó vào IBindingList để xem phương pháp này.

+1

Nó được biết đến như thực hiện giao diện Explicit: http://msdn.microsoft.com/en-us/library/aa288461.aspx – LukeH

+0

@Luke Cảm ơn bạn đã liên kết, tôi đã cố gắng tìm kiếm nó :) –

0

Vấn đề với chiến lược này, nên được thực hiện, đó là phương pháp không thực sự riêng tư. Nếu bạn đã upcast một tham chiếu đến base_class, thì phương thức bây giờ là công khai. Vì đây là phương thức ảo, mã người dùng sẽ thực thi derived_class::do_something() dù nó được đánh dấu là riêng tư.

+2

Trong trường hợp này, đây không phải là lỗi, mà là một tính năng. – sbi

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