2011-11-05 94 views
0

在C#中,如果我們從類繼承,它允許我們覆蓋虛擬方法。如何防止在C#中覆蓋?

這可以通過在方法中不使用virtual關鍵字來防止,但仍然可以通過使用new關鍵字實現方法來隱藏。

有沒有辦法防止覆蓋和陰影,而不使其私有方法?

class myBaseClass{ 
    public void method1(){ //Implementation } 
} 

class myDerivedClass : myBaseClass{ 
    public new void method1() { //new Implementation } 
} 

回答

8

它總是可以隱藏的,但這並不是最重要的 - 它是陰影。瞭解兩者之間的差異很重要。雖然你不能阻止陰影(雖然允許類自身派生),但是不能。你爲什麼想要?你試圖防止什麼不良影響?

密封類本身是雖然一個單獨的選項:

sealed class MyBaseClass { 
    ... 
} 

個人而言,我想封我不設計從得到的任何類,但是這是一個不同的(有爭議的)事。

+0

@ZaheerAhmed:這個*不是*覆蓋,正如我所說的。它是陰影,你無法阻止它。陰影方法雖然不會被稱爲多態。 –

+1

@ZaheerAhmed:如果你明白這不是陰影,請停止叫它重寫......並且你沒有聲明你*有*完全防止陰影 - 你說過你*想要*。如果你有*,你應該立即放棄,或選擇不同的語言。 –

1

標記方法sealed

public sealed void method1() 
{ 
    //Implementation 
} 

當然,你不能完全阻止它。不過,我可能誤解了你的問題,因爲你似乎想要防止陰影,正如Jon Skeet所說的那樣。沒有辦法阻止。

+0

這是方法,而不是類 - 並且非覆蓋方法默認是封閉的。這就是爲什麼OP必須在派生類中使用'new'。 –

+0

@Jon Skeet:固定。 – doctorless

+0

密封類不能被繼承,但我必須允許類的繼承,並且直到它從基類覆蓋時才能密封方法:'sealed override void method1(){// Implementation}' –

2

從閱讀你的問題和你的意見看來,實際的解決方案可能不是在代碼中,而是在理解。

當覆蓋方法(其具有是一個虛擬方法,然後才能將其覆蓋),該方法是呼籲編譯時間類型

的該類型regardsless的任何對象有關的說明在覆蓋和隱藏差見下文

public class BaseClass { 

    public virtual void MyVirtual(){ 
     Console.writeLine("Base virtual"); 
    } 

    public void MyNonVirtual(){ 
     Console.WriteLine("Base non virtual"); 
    } 
} 

public class Derived : BaseClass { 

    public virtual void MyVirtual(){ 
     Console.writeLine("Derived virtual"); 
    } 

    public new void MyNonVirtual(){ 
     Console.WriteLine("Derived non virtual"); 
    } 
} 

BaseClass b = new BaseClass(); 
Derived d = new Derived(); 
BaseClass dAsb = d; 

b.MyVirtual(); //prints Base virtual 
b.MyNonVirtual(); //print Base non virtual 

d.MyVirtual(); //prints Derived virtual 
d.MyNonVirtual(); //print Derived non virtual 

dAsb.MyVirtual(); //prints Derived virtual 
dAsb.MyNonVirtual(); //print Base non virtual 

通知的代碼,最後一行將使用,但從基類b在派生所定義的方法,所述方法因爲它不是虛擬的編譯時間類型決定哪個方法將被調用並且編譯時間類型dAsb是BaseClass。因此即使ddAsb是完全相同的對象,因爲編譯時間類型不同,所以會調用兩個不同的方法。 無論有人隱藏非虛擬方法,任何使用BaseClass編寫的代碼都會按預期工作。