先上题目:
函数ExtendsTest.main()执行后的输出:
public class ExtendsTest {
public static void main(String[] args) {
System.out.println(new B().getValue());
}
static class A {
protected int value;
public A(int value) {
this.value = value;
}
public int getValue() {
try {
value++;
return value;
} finally {
this.setValue(value);
System.out.println(value);
}
}
public void setValue(int value) {
this.value = value;
}
}
static class B extends A {
public B() {
super(5);
setValue(getValue() - 3);
}
@Override
public void setValue(int value) {
super.setValue(2 * value);
}
}
}
为了方便调试,我们先对B类的构造器做一点改装:
public B() {
super(5);
int c = getValue();
setValue(c - 3);
}
开始调试:
这里开始调用this.setValue(),由于子类B自己覆盖了父类的方法,所以这里调用子类的方法,执行后结果为12
也就是说此时的value为B实例的变量value=12,不过要搞清楚的是调用getValue()方法返回的结果是6,返回结果是:
然后是setValue的计算:(6-3)*2=6,此时类B的实例的value值由原先的12变成6。至此,类B实例化完成。
接下来就是调用getValue()的结果了:
value=6+1=7,return 7,打印 2*7=14。最终打印7
所以最终打印结果为: 12 14 7
总结:
- 当子类覆盖父类的方法后,父类里调用同名方法将调用子类的方法,这是继承的特性。
- try...finally块中return 会先行发生(这一点有点迷,明明idea调试的顺序是先执行finally里的语句导致value=12,然后才跳到return,然后执行该方法返回的值还是原先的6,感觉能从函数调用栈帧角度说得通,但这里不熟,未来再回来解疑。)