4

非常に単純な基本クラス:

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を非表示にしていると文句を言い、anewまたはoverrideキーワードのいずれかを追加するように要求します。追加するだけ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 修飾子で変更します。

したがって、基本クラスからバージョンを非表示にしました。これら 2 つのメソッドが同じ名前を持っているという事実は、何の意味もありません。名前が同じように聞こえる2 つのメソッドと同じように関連性はありません。


このような状況は一般的に回避する必要がありますが、コンパイラは常にどのメソッドが呼び出されるかを認識しているため、戻り値があるかどうかがわかりません「the」メソッドに次のようにアクセスした場合:

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

次に、FiguresDrawメソッドが呼び出されます。戻り値は生成されず、期待もされません。

于 2012-06-20T14:09:19.710 に答える
4

ここで起こっていることは、基本要素のメソッドを隠しているということです。事実上、名前が別のものであるかのように、 のDrawメソッドRectangleは新しいメソッドです。

型が のときにこの要素を使用すると、戻り値の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 に答える