[英]Core Java Dynamic Binding
请告诉我们输出的原因。
按照我的说法,使用b.getx(),我们将获得B和b.getx().x
的对象的引用ID b.getx().x
应该获得10的值,但是当我运行此程序时,输出为5。
class Base {
int x = 5;
public Base getx() {
return new Base();
}
}
class Child extends Base {
int x = 10;
public Child getx() {
return new Child();
}
public static void main(String ...s) {
Base b = new Child();
System.out.println(b.getx().x);
}
}
字段访问(与方法调用不同)不受运行时动态调度的影响,它们仅基于编译时类型进行解析。
变量b
是编译时类型Base
,因此b.getx()
也是编译时类型Base
,因此b.getx().x
将被编译为Base的x
字段的访问,而不是Child的访问。 通过查看main
方法的javap
输出来确认这一点:
public static void main(java.lang.String[]);
Code:
0: new #3; //class Child
3: dup
4: invokespecial #4; //Method "<init>":()V
7: astore_1
8: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
11: aload_1
12: invokevirtual #6; //Method Base.getx:()LBase;
15: getfield #7; //Field Base.x:I
18: invokevirtual #8; //Method java/io/PrintStream.println:(I)V
21: return
你可以看到b.getx().x
被编译成Base.x
的getfield
指令。
动态绑定基本上意味着实际调用的方法实现是在运行时确定的,而不是在编译时确定的。 这就是为什么它被称为动态绑定 - 因为将在运行时选择将运行的方法。 动态绑定也称为后期绑定。
Base b = new Child();
是在运行时和动态绑定规则(运行时多态)解决所有与此相关的方法应该在运行时绑定所以...
public Base getx() {
return new Base();
}
这些行返回基类的新实例,您只需在该实例上调用变量。
动态绑定是在运行时查看声明的运行时时间过程。 它也称为后期绑定,其中对重写方法的调用在运行时而不是编译时解析。 在面向对象的系统方法中,覆盖(动态多态)在运行时完成。 当用另一个方法覆盖一个方法时,两个方法的签名必须相同。
例:
class Animal{
public void eat(){
System.out.println("Animals voice");
}
public void go(){
System.out.println("Animals can walk");
}
}
class Dog extends Animal{
public void go(){
System.out.println("Dogs can walk and run");
}
public void eat(){
System.out.println("Dogs can eat a wide range of foods");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.