2016-06-07 58 views
1

說我有一個基類是這樣的:你如何讓成員無法進入子派生類?

public abstract class MyBaseClass 
{ 
    protected void MyMethod(string myVariable) 
    { 
    //... 
    } 
} 

然後我繼承這個類在單獨的程序:

public abstract class MyDerivedClass : MyBaseClass 
{ 
    static readonly string MyConstantString = "Hello"; 
    protected void MyMethod() 
    { 
    MyMethod(MyConstantString); 
    } 
} 

我現在要確保從MyDerivedClass繼承任何其他類完成無法訪問MyBaseClass.MyMethod()方法。 (爲了澄清,我仍然希望能夠調用MyDerivedClass.MyMethod()沒有參數)

我試過使用protected internal但沒有奏效。

更新:我試圖做到這一點,因爲我正在處理的應用程序有一堆使用基類的單獨程序。有5種不同的「類型」的程序,每個都執行一個特定的,獨立的功能,但它們都有一些我想要抽象到這個基類中的通用代碼。通用代碼是99%相同的,只是略有不同,這取決於程序調用它的類型。這就是爲什麼我有我的基類在示例中採用字符串參數,然後消失在派生的基類中,因爲該類知道它執行角色x,因此它會相應地告知其基類。

+1

你的意思是說你不希望他們叫它,或者你不希望它們覆蓋它嗎? –

+0

@MthetheWWatson兩者。 – Logan

+2

你無法阻止它被調用。 –

回答

0

這不太可能。這可能表明你的物體設計可能有問題,但這不是一個問題。

你可以嘗試多一點卑劣的做法,雖然:

public abstract class MyBaseClass 
{ 
    protected abstract string MyConstantString { get; } 

    protected void MyMethod() 
    { 
    //... 
    } 
} 

public abstract class MyDerivedClass : MyBaseClass 
{ 
    protected override sealed string MyConstantString => "Hello"; 
} 

,或者更通常,只需使用構造函數來傳遞所需的參數:從MyDerivedClass衍生

public abstract class MyBaseClass 
{ 
    private readonly string myString; 

    protected MyBaseClass(string myString) 
    { 
    this.myString = myString; 
    } 

    protected void MyMethod() 
    { 
    //... 
    } 
} 

public abstract class MyDerivedClass : MyBaseClass 
{ 
    protected MyBaseClass() : base("Hello") {} 
} 

類沒有在這兩種情況下都可以改變參數,第二種方法從繼承角度來看更好一些(基本上,這個類型是一個關於其祖先類型參數的閉包)。

+0

使用構造函數讓我足夠接近我想要的。我甚至沒有考慮過構造函數! – Logan

2

然後,我會在MyDerivedClass而不是繼承使用組成。所以這個類的所有派生類都不知道MyBaseClass的方法。類MyBaseClass我會使包可見,所以它不可能使用它。

abstract class MyBaseClass 
{ 
    void MyMethod(string myVariable) 
    { 
    //... 
    } 
} 

abstract class MyDerivedClass 
{ 
    static readonly string MyConstantString = "Hello"; 
    private MyBaseClass baseClass; 

    MyDerivedClass(MyBaseClass baseClass) 
    { 
     this.baseClass = baseClass; 
    } 

    protected void MyMethod() 
    { 
    baseClass.MyMethod(MyConstantString); 
    } 
} 

當然應該改變類名。

+0

代表團可能是去這裏的方式,正確的;但是如果你只是在包含類中編寫包裝器(就像你用MyDerivedClass.MyMethod()演示的那樣,它只是調用MyBaseClass.MyMethod()),那麼整個目的就會失敗。如果包含的類邏輯更復雜,委託只是一種解決方案,因此在包裝和包裝之間不存在簡單的1:1關係。 –

0

您無法停止繼承類來調用此方法 - 您已將其設置爲protected,因此您的目的是讓它可以直接或通過其他子類繼承的類訪問它。

如果你想保留的繼承,你能做的最好的是,如果子類MyDerivedClass調用它拋出一個錯誤:

public abstract class MyBaseClass 
{ 
    protected void MyMethod(string myVariable) 
    { 
     Console.WriteLine(myVariable); 
    } 
} 

public abstract class MyDerivedClass : MyBaseClass 
{ 
    static readonly string MyConstantString = "Hello"; 
    protected void MyMethod() 
    { 
     base.MyMethod(MyConstantString); 
    } 

    protected new void MyMethod(string myVariable) 
    { 
     throw new Exception("Not allowed"); 
    } 
} 

public class SubDerivedClass : MyDerivedClass 
{ 
    static readonly string MyConstantString = "Hello"; 
    public void Foo() 
    { 
     MyMethod(MyConstantString); 
    } 
} 

Foo()被稱爲SubDerivedClass,它會調用MyMethodDerivedClass,這將拋出異常。

相關問題