4

一个非常简单的基类:

class Figure {
    public virtual void Draw() {
        Console.WriteLine("Drawing Figure");
    }
}

这个继承类:

class Rectangle : Figure
{
    public int Draw()
    {
        Console.WriteLine("Drawing Rectangle");
        return 42;
    }
}

编译器会抱怨矩形的“绘图”隐藏了图形的绘图,并要求我添加一个newoverride关键字。只需添加new即可解决此问题:

class Rectangle : Figure
{
    new public int Draw() //added new
    {
        Console.WriteLine("Drawing Rectangle");
        return 42;
    }
}

但是,Figure.Draw 有一个 void 返回类型,Rectangle.Draw 返回一个 int。我很惊讶这里允许不同的返回类型......为什么会这样?

4

4 回答 4

6

你真的读过new修改器吗?

使用 new 修饰符显式隐藏从基类继承的成员。要隐藏继承的成员,请在派生类中使用相同的名称声明它,并使用 new 修饰符对其进行修改。

因此,您已经从基类中隐藏了版本。这两个方法具有相同的名称这一事实并不意味着什么 - 它们与两个名称听起来相同的方法没有更多的相关性。


这种情况一般应该避免,但是编译器总是知道要调用哪个方法,从而知道它是否有返回值。如果按如下方式访问“the”方法:

Figure r = new Rectangle();
r.Draw();

然后将调用Figures方法。Draw没有返回值产生,也没有预期。

于 2012-06-20T14:09:19.710 回答
4

这里发生的是您隐藏了基本元素的方法。如此有效,Draw方法 inRectangle是一种新方法,就好像名字是别的东西一样。

如果您在类型为 时使用此元素Rectangle,它将知道返回类型,但如果您尝试使用此实例装箱到基本类型中,则会使用 void 返回类型调用基本方法。

于 2012-06-20T14:10:19.603 回答
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
于 2012-06-20T14:16:33.953 回答
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
于 2012-06-20T14:09:44.753 回答