期待“来自派生的你好”。但得到“基地的你好。”。
class Program
{
interface IBase
{
void Method();
}
public class Base: IBase
{
public virtual void Method()
{
Console.WriteLine("Hello from the base.");
}
}
public class Derived : Base
{
public virtual new void Method()
{
Console.WriteLine("Hello from the derived.");
}
}
static void Main(string[] args)
{
IBase x = new Derived();
x.Method();
}
}
那么为什么不调用派生类的方法呢?更重要的是,如何在不将x转换为Derived类型的情况下调用派生类方法?
在我的实际应用中,IBase有几个其他相关方法,Derived只替换了IBase中的两个方法。
答案 0 :(得分:9)
当您使用new
修饰符时,您明确指出该方法不是该层次结构的虚拟分派链的一部分,因此在基类中使用相同名称调用该方法将不会导致重定向到孩子班。如果您使用override
而不是new
标记方法,那么您将看到您希望看到的虚拟调度。
您还需要从派生类的方法中删除virtual
,因为您无法将override
方法标记为virtual
(它已经是)。
如果您真的不想覆盖该方法,那么在您的情况下,根本不使用继承可能更合适。您可能只想使用接口:
public interface IFoo
{
void Foo();
}
public class A : IFoo
{
public void Foo()
{
Console.WriteLine("I am A, hear me roar!");
}
}
public class B : IFoo
{
public void Foo()
{
Console.WriteLine("I am B, hear me roar!");
}
}
private static void Main(string[] args)
{
IFoo foo = new A();
foo.Foo();
foo = new B();
foo.Foo();
Console.WriteLine();
Console.WriteLine("Press any key to exit . . .");
Console.ReadKey(true);
}
答案 1 :(得分:3)
这是基本的polymorphism。
对于您正在寻找的行为,您需要设置派生方法以覆盖继承的方法:
public class Derived : Base
{
public override void Method()
{
Console.WriteLine("Hello from the derived.");
}
}
答案 2 :(得分:2)
在您的子类中使用override关键字而不是virtual new
。
因此,您的代码应如下所示:
class Program
{
interface IBase
{
void Method();
}
public class Base: IBase
{
public virtual void Method()
{
Console.WriteLine("Hello from the base.");
}
}
public class Derived : Base
{
public override void Method() // The magic happens here!
{
Console.WriteLine("Hello from the derived.");
}
}
static void Main(string[] args)
{
IBase x = new Derived();
x.Method();
}
}
正如here所述,new
关键字用于隐藏父方法,而不是您正在寻找的方法。
答案 3 :(得分:1)
new
关键字创建了一个新方法,并说隐藏了基本方法。但它只适用于派生类的使用者,因为基类代码对它没有任何了解。
override
关键字会使用新的关键字覆盖基类实现。
class Program
{
interface IBase
{
void Method();
}
public class Base: IBase
{
public virtual void Method()
{
Console.WriteLine("Hello from the base.");
}
}
public class Derived : Base
{
// the next line was changed.
public override void Method()
{
Console.WriteLine("Hello from the derived.");
// note that if you want to call the original implementation, you do it like this:
base.Method();
}
}
static void Main(string[] args)
{
Base x = new Derived();
x.Method();
}
}
答案 4 :(得分:0)
Derved中的新方法仅存在于Derived实例中,它有效地隐藏了基本实现。
但IBase类型只知道Base的实现,所以它调用它。
要回答您的问题,请调用派生程序的实现:
Derived d = new Derived();
d.Method();
((IBase)d).Method();
//Prints:
//Hello from the derived.
//Hello from the base.