2010-07-05 65 views
2

我有以下代碼。我需要隱藏界面的一個功能。部分受保護的接口,但沒有抽象類

interface IOne 
{ 
    int FunctionOne(); 
} 

interface ITwo 
{ 
    double FunctionTwo(); 
} 

interface IInterfaceToImplement : IOne, ITwo 
{ 
    void AFunctionToImplement(); 
} 

public abstract MyBaseClass : TheVeryHeavyBaseClass<T, IInterfaceToImplement>, IInterfaceToImplement 
{ 
    public abstract void AFunctionToImplement(); // How to force this one to be protected? 

    public virtual int FunctionOne() { return 0; } 

    public virtual double FunctionTwo() { return 0.0; } 
} 

public MyConcreteClass : MyBaseClass 
{ 
    public override void AFunctionToImplement(); // How to force this one to be protected? 
} 

正如你所看到的我有基類。我需要隱藏AFunctionToImplement()。我有差勁的課程設計嗎?有關如何保護函數不被調用的任何建議?

編輯。在評論中回答Pavel Minaev的問題。

我需要每個具體類實現IInterfaceToImplement中的函數列表。另外我需要每個具體類都能夠存儲IInterfaceToImplement類型的類。 這是樹形數據存儲。存儲的每個「分支」都必須執行與其他分支相同的操作。但除了「根」和其他「分枝」之外,其他人都不得不稱之爲這些操作。

EDIT2我的解決方案。

謝謝馬修雅培和帕維爾米娜夫。我終於意識到我的問題 - 這是大腦。 :)

不,我在開玩笑。 :)問題是 - 我想到了根分支類和同一分支。現在我明白了 - 根不應該執行IInterfaceToImplement。查看解決方案:

public class MyRootClass : IOne, ITwo 
{ 
    private IInterfaceToImplement internalData = new MyConcreteClass(); 

    public int FunctionOne() { return this.internalData.FunctionOne(); } 

    public double FunctionTwo() { return this.internalData.FunctionTwo(); } 
} 
+0

你究竟想要達到什麼目的?接口是定義的公共契約,但將接口定義保密是沒有意義的。有時候讓特定的實現是半私有的是有道理的,但是因爲人們總是可以獲得對同一個對象的接口類型引用,並通過它調用接口方法,所以接口實現永遠也不可能真正是私有的。所以...你想要做什麼? – 2010-07-05 08:04:17

回答

1
public class MyRootClass : IOne, ITwo 
{ 
    private IInterfaceToImplement internalData = new MyConcreteClass(); 

    public int FunctionOne() { return this.internalData.FunctionOne(); } 

    public double FunctionTwo() { return this.internalData.FunctionTwo(); } 
} 
1

接口只能爲公共成員定義。如果你想要一個方法只被定義爲受保護的,那麼不要爲它創建一個接口,而只是將它創建爲抽象基類的受保護抽象成員。即使你使用顯式接口,如果實例是相關接口類型的情況下,它仍然可以公開訪問。

public abstract MyBaseClass<T> : TheVeryHeavyBaseClass<T> 
{ 
    // remove the interface the defined this 
    protected abstract void AFunctionToImplement(); 

    // other code 
} 
+0

我知道這一切。您會在哪裏建議申報受保護的會員(請參閱問題中的代碼)? – 2010-07-05 07:49:58

+0

不幸的是我不能改變'TheVeryHeavyBaseClass'。我不受我控制。 'TheVeryHeavyBaseClass'有兩個通用參數,第二個必須是'IInterfaceToImplement'和MyBaseClass。謝謝你的嘗試! – 2010-07-05 08:30:42

+0

看起來像你自己的選擇將明確暗示界面。然後創建它調用的第二個方法。 – 2010-07-05 17:31:40

2

我會建議使用顯式接口實現:

void IInterfaceToImplement.AFunctionToImplement(); 

...但是,這不會讓你揭露和實現在子類中的方法,仍然有它隱藏起來。在這種情況下,您可能想重新考慮您的班級設計。

你最好的選擇,它像以下:

public interface IMyInterface 
{ 
    void DoWork(); 
} 

public abstract class MyInterfaceBase : IMyInterface 
{ 
    /// <summary> 
    /// Forced implementation. 
    /// </summary> 
    protected abstract void DoWork(); 

    /// <summary> 
    /// Explicit implementation. 
    /// </summary> 
    void IMyInterface.DoWork() 
    { 
     // Explicit work here. 

     this.DoWork(); 
    } 
} 

這仍然留下,而不是MyInterfaceBase參考其公開曝光,如果該方法是從IMyInterface的參考又稱爲DoWork的的問題。你根本無法解決這個問題。如果我做了以下內容:

MyInterface first = new MyInterface(); // Let's assume I have implemented MyInterface : MyInterfaceBase 
first.DoWork(); // Compile error, can't access method here. 

鑑於:

IMyInterface second = new MyInterface(); 
second.DoWork(); // No problem. 

你能看到的問題?

+0

歡迎任何設計方案!隨時建議對我的課程設計進行任何更改。 :) – 2010-07-05 07:52:08

+1

問題是,爲什麼你需要隱藏這種方法? – 2010-07-05 07:53:26

+0

實際上,子類可以重新實現顯式接口實現。他們不能做的是通過'base'調用基類的實現(因爲它實際上是私有的)。但是我們總是可以聲明'protected virtual AFunctionToImplement',以此來界定顯式接口,並且將後者委託給前者。這樣,子類可以覆蓋那個_and_使用'base'。 – 2010-07-05 08:02:44

1

每當你編寫一個接口時,你都隱式地聲明瞭實現它的任何類的公共視圖,所以試圖隱藏它的方法是沒有意義的。你可以從界面中取出AFunctionImplementation,並將它留在MyBase類中。任何MyBase類的實現仍然可以訪問它。

在這種情況下您還可以使MyBase類直接實現IOne和ITwo。

將一個名爲'Implementation'的函數作爲其名稱的一部分將是一個很好的提示,可以避免將其放入界面中,因爲通常將界面用作隔離使用情況與實現細節的手段。

+0

我認爲你的建議。問題是'TheVeryHeavyBaseClass'的第二個通用參數,MyBaseClass必須實現相同的單一接口(但不是兩個)。 – 2010-07-05 08:33:40

1

也許你可以使該方法在虛擬抽象類,然後拋出一個異常

/// <summary> 
    /// Available only in derived classes 
    /// </summary> 
    public virtual void AFunctionToImplement2() 
    { 
     throw new ProtectedMethodException("Please do not call this method in the base class:) "); 
    } 

我不知道這是一個愚蠢的解決方案,但至少你不允許用戶即使它是公開的,也使用該方法。

+0

這是類的實現方式。試圖避免這一點。 – 2010-07-05 08:50:03