先看两个例子
package com.middle.test;
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
BBB bbb = new BBB();
System.out.println(bbb.cal()); //结果是40
}
}
class AAA {
public int i = 10;
public int cal() {
return i + 10;
}
}
class BBB extends AAA{
public int i = 20;
@Override
public int cal() {
return i + 20;
}
}
package com.middle.test;
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
BBB bbb = new BBB();
System.out.println(bbb.cal()); //结果是20
}
}
class AAA {
public int i = 10;
public int cal() {
return i + 10;
}
}
class BBB extends AAA{
public int i = 20;
// @Override
// public int cal() {
// return i + 20;
// }
}
大部分人对第一个结果都能想对。对第二个结果想不通。
成员方法在执行的过程中,JVM会将方法和当前调用对象实际内存进行绑定。
通俗点说,bbb是BBB对象,当调用bbb.cal(),会在BBB中寻找cal()。如果找不到才会去父类。所以,调用子类的方法,都是先在子类中寻找,然后再去父类中。
但是属性是没有动态绑定机制的,属性在哪里声明在哪里使用
因此,第二个例子,bbb.cal()调用了父类AAA.cal(),AAA.cal()中的i指的是AAA中的属性。