2011-08-30 163 views

回答

29

下面是一個例子,爲什麼它沒有意義的,能夠覆蓋可視性:

interface someI 
{ 
    void doYourWork(); 
} 
public class A : someI 
{ 
    public void doYourWork() 
    { 
     //... 
    } 
} 

public class B : someI 
{ 
    private void doYourWork() 
    { 
     //... 
    } 
} 
void Main() 
{ 
    List<someI> workers = getWorkers(); 
    foreach(var worker in workers) 
     worker.doYourWork(); 
} 

當你的員工是B型的,會發生什麼?你正在調用一個方法,就好像它是公開的,但它是一個私有方法。如果你想要這個功能,那麼它不是一個真正的私人方法嗎?

如果你只希望它是公衆通過你的接口引用時,那麼你可以將它定義爲這樣的:

public class B : someI 
{ 
    void someI.doYourWork() 
    { 
     //... 
    } 
} 

而且你結束了這一點:

var b = new B(); 
b.doYourWork(); // Not accessible 
((someI)b).doYourWork(); // Accessible 
+3

我建議,對於未密封的類,其實現不會暴露具有相同名稱和簽名的公共類成員的接口應該使用受保護的虛擬成員來實現;不幸的是,最接近的人可以在C#中這樣做,就是讓接口實現簡單地調用受保護的虛擬方法。否則,如果派生類重新實現接口,則無法調用父實現。 – supercat

+1

@supercat也許這只是早,但我不知道我跟着你;你是什​​麼意思?否則,如果一個派生類重新實現一個接口,將無法調用父實現?爲什麼你想要一個實現接口的受保護方法(在這種情況下,你將無法通過接口訪問它;只有在派生類中,它甚至可能不知道它們實現的接口) – Rob

+2

In vb.net ,可以這樣說:'Protected Overridable Sub DoSomethingImpl()Implements IDoSomething.DoSomething';外部代碼將只能通過接口調用該方法,但派生類將能夠覆蓋該方法,並在覆蓋內調用父方法。在C#中,能夠同樣使用受保護的方法來實現接口會很有用,但負責規範的人員不允許使用該選項。最接近的可能是用一個可以調用受保護方法'DoSomethingImpl()'的方法顯式實現接口。請注意... – supercat

20

必須實施方法public,因爲它們必須通過接口進行調用,從而可以將接口作爲類型進行訪問。

您在這裏有幾個選項「change」該方法的可見性。鑑於:

public interface IFoo 
{ 
    bool IsFoo(); 
} 

A.實現該方法explicitly

public class Foo : IFoo 
{ 
    bool IFoo.IsFoo() { return true; } 
} 

的方法將只可通過接口

B.改變的可見性(在這種情況下IFoo。)接口

定義接口爲internal而不是public。因此,Foo也必須是internal

+0

的其他語言作爲vb.net,實現接口的方法不需要特定的輔助功能。 C#要求隱式接口實現必須是公有的,因爲沒有其他的關鍵字或符號表明一個已命名的類成員也應該被視爲接口實現。 – supercat

5

要求接口實現是公開的只是一個合乎邏輯的要求。當你實現一個接口時,你告訴編譯器「嘿,我在這個接口上實現了每種方法」。因此,將該方法設置爲私有使其不再可訪問 - 並且邏輯上不實現。接口作爲使用你的對象的代碼的契約,說你總是可以調用我的對象的接口中定義的任何方法。如果實施方法是私人的,那將不再是事實。

如果你想隱藏你的實現,比如說Intellisense,那麼你可以簡單地像@Bryan提到的那樣直接實現這個方法。

+0

「接口作爲使用您的對象的代碼合同,表示您始終可以調用在對象接口中定義的任何方法。」這不完全正確。這意味着您可以將類的實例轉換爲接口,然後_then_通過接口引用調用接口方法。這是合同,而不是在沒有首先投射到界面的情況下調用界面方法的能力。當然,你通常應該公開接口方法而不要求演員,但這既不是技術要求也不總是合乎邏輯的要求。 – Darryl

相關問題