簡體   English   中英

部分受保護的接口,但沒有抽象類

[英]Partially protected interface but without abstract class

我有以下代碼。 而且我需要隱藏界面的一項功能。

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我的解決方案。

感謝Matthew Abbott和Pavel Minaev。 我終於意識到我的問題-這是大腦。 :)

不,我在開玩笑。 :)問題是-我認為根類和分支類與同一分支相同。 現在我明白了-根目錄不應該實現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(); }
}

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

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();
    }
}

如果從IMyInterface引用而不是MyInterfaceBase引用調用該方法,則仍然存在公開公開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.

你看到這個問題了嗎?

只能為公共成員定義接口。 如果要只將方法定義為受保護的方法,則不要為其創建接口,而只需將其創建為抽象基類的受保護抽象成員即可。 即使您使用顯式接口,如果該實例屬於相關接口類型,它仍然可以公開訪問。

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

    // other code
} 

每當您編寫接口時,您都在隱式聲明一個實現該接口的任何類的公共視圖,因此嘗試隱藏其方法根本沒有任何意義。 您可以將AFunctionImplementation移出接口,並將其保留在MyBase類中。 MyBase類的任何實現仍然可以訪問它。

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

在名稱中使用“ Implementation”一詞作為功能的一部分將是避免將其放在接口中的一個很好的提示,因為接口通常被用作將用法與實現細節隔離開的手段。

也許您可以在抽象類中將方法虛擬化,然后引發異常

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

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

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

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM