在对象的封装继承多态中,java的动态绑定机制非常重要
话不多说,先上定义
- 当调用对象方法的时候,该方法会和该对象的内存地址\运行类型绑定
- 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用。
我们用代码来解释这是什么意思
class A {
public int i = 10;
public int sum() {
return getI() + 10;
}
public int getI() {
return i;
}
public int sum1() {
return i + 10;
}
}
class B extends A {
public int i = 20;
public int sum() {
return getI() + 20;
}
public int getI() {
return i;
}
public int sum1() {
return i + 10;
}
}
public static void main(String[] args) {
A a = new B();
System.out.println(a.sum());
System.out.println(a.sum1());
}
请看以上代码,会输出什么?
首先我们分析一下A和B,B继承A,两个类都有sum,getI,sum1方法
a的运行类型是B所以当调用a的方法时,会找B类的方法调用
那么这很好分析了,sum返回40一个sum1返回30。
这只是开始,如果我把B类中的sum和sum1注释了,代码输出什么?
class A {
public int i = 10;
public int sum() {
return getI() + 10;
}
public int getI() {
return i;
}
public int sum1() {
return i + 10;
}
}
class B extends A {
public int i = 20;
// public int sum() {
// return getI() + 20;
// }
public int getI() {
return i;
}
// public int sum1() {
// return i + 10;
// }
}
public static void main(String[] args) {
A a = new B();
System.out.println(a.sum());
System.out.println(a.sum1());
}
我们来仔细分析一下。
当调用B类中sum时,没有找到。根据继承的机制,会从父类A中找。
找到A中的sum方法了。sum方法调用getI,这时候有一个关键的问题。getI到底调用的是A类的还是B类的?两个getI返回的i可不一样。
不卖关子了,直接回看我们一开始所提出的规则。
当调用对象方法的时候,该方法会和该对象的内存地址\运行类型绑定
现在的运行类型是B,所以找getI方法会先从B中找。所以sum的结果应该是20+10 = 30
现在再看sum1
B类中找不到,还是去A中找。
sum1方法中,i是用B类的还是A类的?
当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用。
根据这个规则,i应该是直接使用A类的i了。最后返回10+10=20
运行看一下结果