2009-06-23 110 views
5

比方說,我有以下代碼:C#繼承

interface ISomeInterface 
{ 
    void DoSomething(); 
    void A(); 
    void B();  
} 

public abstract class ASomeAbstractImpl : ISomeInterface 
{ 
    public abstract void A(); 
    public abstract void B(); 
    public void DoSomething() 
    { 
     // code here 
    } 
} 

public class SomeImpl : ASomeAbstractImpl 
{ 
    public override void A() 
    { 
     // code 
    } 

    public override void B() 
    { 
     // code 
    } 
} 

的問題是,我希望有ASomeAbstractImpl.DoSomething()方法密封(最終),所以沒有其他的類都可以實現它。 由於代碼現在SomeImpl可能有一個名爲DoSomething()的方法,可以調用它(它不會覆蓋與抽象類名稱相同的方法,因爲它沒有標記爲虛擬),但我想切斷在SomeImpl類中實施這種方法的可能性。

這可能嗎?

回答

9

C#中的方法默認是封閉的。然而,沒有什麼可以做來防止方法隱藏(在派生類中暴露一個名稱相同的方法,通常使用new)。

或者,對於這個問題,接口重新實現:

static void Main() 
{ 
    ISomeInterface si = new EvilClass(); 
    si.DoSomething(); // mwahahah 
} 

public class EvilClass : ASomeAbstractImpl, ISomeInterface 
{ 
    public override void A() {} 
    public override void B() { } 
    void ISomeInterface.DoSomething() 
    { 
     Console.WriteLine("mwahahah");    
    } 
} 
2

所有方法默認情況下密封的,但沒有阻止會員隱藏的方式。

無論何時隱藏成員,C#編譯器都會發出編譯器警告,但除此之外,您無法阻止它。

+5

只有在您意外操作時纔會發出警告;添加「新」限定符,它關閉... – 2009-06-23 07:31:55

0

如果SomeImpl類包含DoSemthing方法,這意味着它隱藏了原始一個不越權。

0

當處理接口和抽象類時,更多的是關於你必須做什麼,而不是你不能做什麼。因此,您可以讓接口用戶知道這些是他們必須實現的方法,並且您可以使用關鍵字虛擬關鍵字來讓他們知道可以覆蓋某個方法。但是你不能阻止他們做太多事情。即使您有意不使用虛擬關鍵字,他們仍然可以用關鍵字隱藏它。