2010-11-07 56 views
4

我需要在調用overriden之後自動調用基類方法(如構造函數call base)。例如:自動調用基本方法

class A 
{ 
    public void Fun() 
    { 
     Console.Write("Class A!"); 
    } 
} 

class B : A 
{ 
    public void Fun() 
    { 
     Console.Write("Class B!"); 
    } 
} 

我想看到的屏幕

A級上! B類!

執行下面的代碼時:

B b = new B(); 
b.Fun(); 

誰能告訴我,請有什麼需要在示例代碼來改變或如何更好地編寫得到需要的結果?謝謝。

回答

18

如果你不想顯式調用它,因此確保A.Fun()被稱爲在派生類中做,你可以使用一種叫做template method pattern

class A 
{ 
    public void Fun() 
    { 
     Console.Write("Class A!"); 
     FunProtected(); 
    } 

    protected virtual void FunProtected() 
    { 
    } 
} 

class B : A 
{ 
    protected override void FunProtected() 
    { 
     Console.Write("Class B!"); 
    } 
} 

這將使你:

new A().Fun() -> "Class A!" 
new B().Fun() -> "Class A! Class B!" 
+0

@Kirkham感謝您糾正我的拼寫,並澄清我的答案:) – 2010-11-07 18:06:55

+3

+1受保護的樂趣。你永遠不知道周圍有什麼...... – 2013-04-24 00:58:43

8

如果你想要這樣的行爲,你需要改變平臺/語言。 .NET不會自動調用基本方法。你需要明確地調用它。當你這樣做

class A 
{ 
    public virtual void Fun() 
    { 
     Console.Write("Class A!"); 
    } 
} 

class B : A 
{ 
    public override void Fun() 
    { 
     // call the base method which will print Class A! 
     base.Fun(); 
     Console.Write("Class B!"); 
    } 
} 

現在:

B b = new B(); 
b.Fun(); 

你會得到所需要的結果也是你的方法必須是virtual或者你會在派生類中隱藏它。

+0

「另外你的方法需要是虛擬的,否則你會將它隱藏在派生類中」對於海報想要的行爲,我不確定它需要是虛擬的。 – strager 2010-11-07 18:00:28

+1

@strager,如果它不是虛擬的,你會得到一個編譯器警告。 – 2010-11-07 18:01:52

+1

您可以使用new關鍵字在不使用虛擬方法的情況下襬脫警告。 – 2010-11-07 18:20:30

2

仍然可以這樣:

interface IFun 
{ 
    void Fun(); 
} 

abstract class A : IFun 
{ 
    void IFun.Fun() 
    { 
     Console.Write("Class A!"); 
     Fun(); 
    } 
    protected abstract void Fun(); 
} 

class B : A 
{ 
    protected override void Fun() 
    { 
     Console.Write("Class B!"); 
    } 
} 

IFun b = new B(); 
b.Fun(); 

這工作如果o對象引用是IFun。

+0

但我不能以這種方式創建A類的實例。已經給出了很好的答案。 – 2011-05-20 10:21:51

0

僅供參考,您可以使用將A放入B中的包裝模式。下面是一個原油示例!

interface IFunClass { 
    void Fun(); 
} 

class A : IFunClass { 
    public void IFunClass.Fun() { 
     Console.Write("Class A!"); 
    } 
} 

class B : IFunClass { 
    public B(IFunClass f) { 
     this.m_SomethingFun = f; 
    } 

    public void IFunClass.Fun() { 

     this.m_SomethingFun.Fun(); 

     Console.Write("Class B!"); 
    } 

    private IFunClass m_SomethingFun; 
} 

A a = new A(); 
B b = new B(a); 

b.Fun() // will call a.Fun() first inside b.Fun()