2012-01-30 182 views
10

a.doStuff()方法是否可以在不編輯A類的情況下打印「B did stuff」?如果是這樣,我該怎麼做?從父項調用子類方法

class Program 
{ 
    static void Main(string[] args) 
    { 
     A a = new A(); 
     B b = new B(); 

     a.doStuff(); 
     b.doStuff(); 

     Console.ReadLine(); 
    } 
} 

class A 
{ 
    public void doStuff() 
    { 
     Console.WriteLine("A did stuff"); 
    } 
} 

class B : A 
{ 
    public void doStuff() 
    { 
     Console.WriteLine("B did stuff"); 
    } 
} 

我正在改裝蒸汽遊戲Terraria。而且我不想反編譯並重新編譯它,因爲這將會產生蒸汽。我的程序通過XNA「注入」Terraria。我可以使用XNA的update()和draw()方法來修改一些內容。但它非常有限。我不想重寫基本方法來修改更多的東西(例如worldgen)。

回答

13

是的,如果您在A中聲明doStuffvirtual,然後在B中聲明override

class A 
{ 
    public virtual void doStuff() 
    { 
     Console.WriteLine("A did stuff"); 
    } 
} 

class B : A 
{ 
    public override void doStuff() 
    { 
     Console.WriteLine("B did stuff"); 
    } 
} 
+0

由於A.doStuff只是被覆蓋,所以它應該是抽象的而不是虛擬的。 – 2014-11-18 21:21:17

2

由於B通過繼承實際上是A,並且該方法被重載。

A a = new B(); 
a.doStuff(); 
+2

當然,它可以通過虛擬和覆蓋來完成,但這是唯一的方法來做到這一點,而不需要根據請求改變A OP – 2012-01-30 17:24:26

+0

謝謝,但我也做不到。我可能應該在OP中澄清這一點;我正在改裝一款蒸汽遊戲Terraria。而且我不想反編譯並重新編譯它,因爲這將會產生蒸汽。我的程序通過XNA「注入」Terraria。我可以使用XNA的update()和draw()方法來修改一些內容。但它非常有限。我不想重寫基本方法來修改更多的東西(例如worldgen)。 – user1178494 2012-01-30 17:41:38

+0

@ user1178494使用可能有所幫助的新關鍵字查看我的更新答案。 – VS1 2012-01-30 18:08:58

0

類代碼中的& B您已經發布將反正生成以下編譯器警告,並會要求用B類的new關鍵字,雖然會編譯: new關鍵字是必需的「 B.doStuff()」,因爲它隱藏繼承的成員 'A.doStuff()'

使用method hiding與類映射器和B類newvirtual關鍵字沿着如下:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Mapper a = new B(); //notice this line 
     B b = new B(); 

     a.doStuff(); 
     b.doStuff(); 

     Console.ReadLine(); 
    } 
} 

class A 
{ 
    public void doStuff() 
    { 
     Console.WriteLine("A did stuff"); 
    } 
} 

class Mapper : A 
{ 
    new public virtual void doStuff() //notice the new and virtual keywords here which will all to hide or override the base class implementation 
    { 
     Console.WriteLine("Mapper did stuff"); 
    } 
} 

class B : Mapper 
{ 
    public override void doStuff() 
    { 
     Console.WriteLine("B did stuff"); 
    } 
} 
+0

謝謝,但是當調用a.doStuff()時,這仍然會打印出「A did stuff」。 – user1178494 2012-01-30 18:15:04

+0

@ user1178494我已經更新了我的答案,請嘗試一下,注意A類和B類之間使用Mapper(Mediator)類,請看看它是否可以解決您的問題。 – VS1 2012-01-30 19:52:06

+0

不幸的是,它仍然無法正常工作。再次感謝您的幫助。 – user1178494 2012-01-30 20:15:33