2012-01-30 119 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