0

我对java多态性感到困惑。在动态方法绑定中,jvm 在运行时决定必须调用哪个类方法。假设我有 A、B 和 C 三个班级。

class A{
    int get(){
        return 10;
    }

    int getParent(){
        return 10;
    }
}

class B extends A
{
    int get(){
        return 20;
    }
}

public class C
{
    public static void main(String args[])
    {
        A a = new A();
        A a1 = new B();
        System.out.println(a.get());/////////////////////////LINE1    
        System.out.println(a1.get  ());////////////////////////LINE2    
        System.out.println(a.getParent());////////////////////////LINE3
    }
}

我在编译时和运行时绑定的第 1 行和第 3 行有混淆。在第 3 行中,它是 a.getParent(),并且此方法仅在父类中,因此它必须在运行时决定。

在第 1 行中,引用和对象都来自同一个类,所以它必须再次决定。

请向我发送运行时和编译时绑定如何工作的任何好的链接。

4

4 回答 4

3
    class A
    {
      public doIt( )
      {
        //this does something
      }
    }

    class B extends A
    {
      public doIt( )
      {
        //this does something
      }
    }

    class C extends B
    {
      public doIt( )
      {
        //this does something
      }

    }        

    public static void main(String[] args) {
          A x = new B( );

          x.doIt( );

    }

引起很多混乱的语句是“A x = new B();” 陈述。尽管变量 x 是 A 类型的对象,但它被实例化为 B 类的对象——因为“= new B( );” 声明的一部分。Java 运行时基本上会看这个语句并说“即使 x 被明确声明为类型 A,它也被实例化为 B 类的对象,所以我将运行 B 类中定义的 doIt() 方法的版本。”

由对象 x 执行的 doIt() 方法的版本是 B 类中的版本,因为在 Java 中称为动态绑定——上面的代码可以被认为是动态绑定的一个示例。动态绑定基本上意味着实际调用的方法实现是在运行时确定的,而不是在编译时确定的。这就是为什么它被称为动态绑定——因为将要运行的方法是在运行时选择的。动态绑定也称为后期绑定。

早期绑定中,数据和方法在编译时绑定,而在后期绑定中,数据和方法将在运行时绑定。

于 2012-12-12T11:04:21.567 回答
0

B 类覆盖get() 方法。因此,每当您在B类型的对象上调用 get() 时,它将使用被覆盖的方法。

因为 B 没有覆盖 getparent(),所以当你在 B 类上调用它时,父 getParent() 将被调用

于 2012-12-12T10:58:43.143 回答
0

A 类为 Object 实例a提供了一个虚方法表,其中包含 A.get 和 A.getParent。

B 类为 Object 实例a1提供了一个虚拟方法表,该表首先取自 A 类,并进行了扩展(此处没有可扩展的内容)。该get方法被 B.get 覆盖。

a1.get,即使是 A,也会调用 B.get。

于 2012-12-12T11:02:55.483 回答
0

这里的多态性仅适用于 line2 的情况。没有适用于 line1 和 line3 的多态性概念。

于 2012-12-12T11:09:28.470 回答