我在关于“后期绑定”概念的“多态性”一章中的“思考java”中读到,我只想知道我对这个概念的理解是否正确
程序语言知道在运行时之前要执行的函数在哪里
if(condition){func1();}else{func2();}
因此,在程序运行之前,每个可能函数的地址都是准确知道的,所以它很容易编译,但是在OOL中检查这段代码,
makeItSpeak(Animal a ){
a.speak();
}
虽然a可能是狗,猫或任何其他Animal类型,并且因为我们在运行时初始化对象,所以我们必须传递我们在运行时运行的参数,所以这是后期绑定发生在运行时......
这是真的吗?
答案 0 :(得分:4)
是的,它是使用virtual method table实现的。
在您的示例中,speak()
是一个没有物理地址的虚拟(抽象)方法。在运行时,基于具体Animal
子类的类型,运行时通过引用虚方法表来确定要调用的speak()
实现。
答案 1 :(得分: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,只能在运行时确定。
此规则中的问题是静态方法,它们在编译时受到限制,因此请注意。
答案 2 :(得分:1)
是的,你是对的。在您给出的示例中,要调用的正确speak()
取决于在运行时将知道的对象类型。只有当您将方法声明为最终时,才需要提前绑定。
答案 3 :(得分:0)
是的,你做得对。它使代码更具可扩展性和强大性。