2

我在“Polymorphism”一章的“Thinking in java”中读到了“后期绑定”的概念,我只是想知道我对这个概念的理解是否正确

例如,过程语言知道在运行时之前要执行的函数在哪里

if(condition){func1();}else{func2();}

所以每个可能的函数的地址在程序运行之前是准确地知道的,所以它很容易编译,但是在 OOLs 中检查这个代码,,

makeItSpeak(Animal a ){
  a.speak();
}

虽然 a 可能是 dog 、 cat 或任何其他 Animal 类型,并且因为我们在运行时初始化对象,所以我们必须在运行时传递我们运行 speak 的参数,所以这是在运行时发生的后期绑定-时间 ....

真的吗 ??

4

4 回答 4

4

是的,它是使用虚拟方法表实现的。

在您的示例speak()中是一个没有物理地址的虚拟(抽象)方法。在运行时,根据具体子类的类型,运行时通过引用虚方法表来确定调用Animal哪个实现。speak()

于 2010-10-01T02:14:42.960 回答
2

是的。例如,

class A {
  void a() { System.out.println("A"); }
}

class B extends A {
  void a() { System.out.println("B"); }
}

class C {
  public static void main (String[] args) {
    A anA = new B();
    anA.a();  // This will print B
  }
}

即使变量 anA 是 A 类型,但实例是 B,只能在运行时确定。

这条规则中的问题是静态方法,它们在编译时被绑定,所以要小心。

于 2010-10-01T02:15:45.410 回答
1

是的,你是对的。在您给出的示例中,正确speak()调用取决于运行时已知的对象类型。只有当您将方法声明为final时,它才会受到早期绑定。

于 2010-10-01T02:18:19.043 回答
0

是的,你没看错。它使代码更具可扩展性和功能性。

于 2010-10-01T02:20:41.740 回答