public class A {
public int i = 10;
public int sum() {
return getI() +10;
}
public int sum1() {
return i+10;
}
public int getI() {
return i;
}
}
public class B extends A { //子类
public int i = 20;
public int sum() {
return i+20;
}
public int getI() {
return i;
}
public int sum1() {
return i+10;
}
}
public class MainAB {
public static void main(String[] args) {
A a = new B(); //向上转型
System.out.println(a.sum());//40
System.out.println(a.sum1());//30
}
}
当我把B类`getI`方法注销时。
public class B extends A { //子类
public int i = 20;
// public int sum() {
// return i+20;
// }
public int getI() {
return i;
}
public int sum1() {
return i+10;
}
}
a的编译类型A,运行类型是B,所以当它一旦走方法先找子类B,但是子类B没有sum()方法,它就会去找父类sum()方法 但是父类A的sum()方法调用的是getI(),但是子类B和父类A都有getI()方法
根据Java的动态绑定机制
Java的动态绑定机制
1. 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定。
2. 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
所以,a.sum()会调用子类B的getI 结果为30
接下来把子类sum1也注销
public class B extends A { //子类
public int i = 20;
// public int sum() {
// return i+20;
// }
public int getI() {
return i;
}
// public int sum1() {
// return i+10;
// }
}
现在探讨a.sum1()的运行结果
System.out.println(a.sum1());
因为编译类型是A,运行类型是B,所以会先找B类的sum1,但是B没有sum1方法,所以会向上找A类的sum1()方法,但是sum1返回i+10,由于属性没有动态绑定机制,所以会使用在A类定义的i属性返回20。
总结:
Java的动态绑定机制
1. 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定。
2. 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用