0

私は次のクラスを持っています:

class Polygon
{
    protected string name;
    protected float width, height;
    public Polygon(string theName, float theWidth, float theHeight)
    {
        name = theName;
        width = theWidth;
        height = theHeight;
    }
    public virtual float calArea()
    {
        return 0;
    }
}

class Rectangle : Polygon
{
    public Rectangle(String name, float width, float height) : base(name,width,height)
    {
    }
    public override float calArea()
    {
        return width * height;
    }
}

主な機能1:

   static void Main(string[] args)
    {
        Rectangle rect1  = new Rectangle("Rect1", 3.0f, 4.0f);
        float Area = rect1.calArea()
    }

主な機能 2:

 static void Main(string[] args)
    {
        Polygon poly = new Rectangle("Rect1", 3.0f, 4.0f);
        float Area = poly.calArea()
    }

Main 関数 2 が動的バインディングを使用することを理解しています。
Rectangle クラスの calArea メソッドで override キーワードを new に変更すると、静的バインディングになります。メイン関数 1 はどうですか? 静的/動的バインディングを使用していますか?

4

2 に答える 2

2

「動的」バインディングがこれに適しているとは思いません。コンパイル時(静的)および実行時のバインディングについて話している。クラスが Rectangle から継承されていない場合 - 例 1 では、コンパイラがどのメソッドを呼び出すかを決定するのに十分な情報があり、コンパイル時 (静的) バインディングを実行できます。

[編集]:

どうやら私は正しくなかったようです。例 1 の生成された IL コードと、「オーバーライド」の代わりに「新規」を使用した例 2 を調べたところ、メイン関数のコードは同じように見えます。

  IL_000f:  newobj     instance void Console.Program/Rectangle::.ctor(string,
                                                                          float32,
                                                                          float32)
  IL_0014:  stloc.0
  IL_0015:  ldloc.0
  IL_0016:  callvirt   instance float32 Console.Program/Polygon::calArea()

このコードから、例 1 でも、callArea メソッドが Polygon クラスから呼び出されていることがわかります。そのため、IL コードにコンパイルする段階では、正確なメソッド実装へのバインドはありません。

于 2013-03-22T11:26:12.067 に答える
0

非仮想メソッドは静的にバインドされます。つまり、コンパイル時にどのメソッドを呼び出すかがわかります。新しいキーワードを指定することにより、これが仮想/オーバーライド領域外であることをコンパイラーに通知します。

新しいキーワードを定義しないメイン関数1、AFAIKは、仮想オーバーライドのスコープ内にあるため、動的バインディングを使用します。

于 2013-03-22T11:17:10.000 に答える