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()
    }

我了解主要功能 2 使用动态绑定。
如果我在 Rectangle 类的 calArea 方法中将 override 关键字更改为 new,则它是静态绑定。主要功能1呢?它使用静态/动态绑定吗?

4

2 回答 2

2

我不认为“动态”绑定是正确的词。您正在谈论编译时(静态)和运行时绑定。如果没有从 Rectangle 继承类 - 那么在示例 1 中,编译器有足够的信息来决定将调用哪个方法,并且它可以进行编译时(静态)绑定。

[编辑]:

显然我是不对的。我检查了示例 1 和示例 2 生成的 IL 代码,使用“new”而不是“override”,Main 函数的代码似乎相同:

  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

非虚拟方法是静态绑定的,这意味着它在编译时就知道要调用哪个方法。通过提供 new 关键字,您告诉编译器这是虚拟/覆盖区域。

主要功能 1 没有定义 new 关键字,AFAIK 将使用动态绑定,因为它仍然在虚拟覆盖的范围内。

于 2013-03-22T11:17:10.000 回答