一个非常简单的基类:
class Figure {
public virtual void Draw() {
Console.WriteLine("Drawing Figure");
}
}
这个继承类:
class Rectangle : Figure
{
public int Draw()
{
Console.WriteLine("Drawing Rectangle");
return 42;
}
}
编译器会抱怨Rectangle的“Draw”隐藏了Figure的Draw,并要求我添加new
或override
关键字。只需添加new
即可解决此问题:
class Rectangle : Figure
{
new public int Draw() //added new
{
Console.WriteLine("Drawing Rectangle");
return 42;
}
}
但是,Figure.Draw有一个void返回类型,Rectangle.Draw返回一个int。我很惊讶这里允许不同的返回类型......为什么会这样?
答案 0 :(得分:6)
你真的读过new
modifier吗?
使用new修饰符显式隐藏从基类继承的成员。要隐藏继承的成员,请使用相同的名称在派生类中声明它,并使用new修饰符对其进行修改。
所以,你已经隐藏了基类的版本。这两个方法具有相同名称的事实并不意味着什么 - 它们与名称声音相同的两个方法没有关系。
通常应避免这种情况,但编译器将始终知道要调用哪个方法,因此它是否具有返回值。如果按如下方式访问“the”方法:
Figure r = new Rectangle();
r.Draw();
然后将调用Figure
s Draw
方法。没有产生任何回报价值,也没有预料到。
答案 1 :(得分:4)
这里发生的是你隐藏了基本元素的方法。实际上,Draw
中的Rectangle
方法是一种新方法,就好像名称是其他内容一样。
如果在类型为Rectangle
时使用此元素,它将知道返回类型,但如果您尝试将此实例用于基类型,则将使用void返回类型调用基本方法
答案 2 :(得分:4)
new
关键字只是告诉编译器此方法不会覆盖基本方法,而只是具有相同的名称。它不会被来自基类的虚拟调用执行。
class Base
{
public virtual void A()
{
Console.WriteLine("Base::A");
}
public virtual void B()
{
Console.WriteLine("Base::B");
}
}
class Derived : Base
{
public override void A()
{
Console.WriteLine("Derived::A");
}
public new int B()
{
Console.WriteLine("Derived::B");
}
}
所以,
Base obj = new Derived();
obj.A();
obj.B();
将输出
Derived::A
Base::B
答案 3 :(得分:2)
使用“new”关键字,您只能从Rectangle引用中调用int Draw。没有运行时方法解析。
Rectangle r = new Rectangle();
Figure f = r;
f.Draw(); // calls the void method Figure.Draw
int x = r.Draw(); // calls the int method Rectangle.Draw