java 类之间的调用_随笔53 java存在继承关系的类之间的调用

1 /**

2 * Created by zmt on 2016/12/22.3 */

4 public classTest {5 public static voidmain(String [] args){6 System.out.println(newB().getValue());7 }8 static classA{9 protected intvalue;10 public A(intv) {11 setValue(v);12 }13 public void setValue(intvalue){14 this.value =value;15 }16 public intgetValue(){17 try{18 value++;19 returnvalue;20 } catch(Exception e){21 System.out.println(e.toString());22 } finally{23 this.setValue(value);24 System.out.println(value);25 }26 returnvalue;27 }28 }29 static class B extendsA{30 publicB() {31 super(5);32 setValue(getValue() - 3);33 }34 public void setValue(intvalue){35 super.setValue(2 *value);36 }37 }38 }

调试看下执行过程。

首先是main方法,new了一个B对象,然后就是调用该对象的getValue()方法,这个没什么好说的。

65c464248308e8a949d9670f3665b7f1.png

接下来就要执行B类的构造方法了,这个也没啥说的

2141dc8217643e330eb9cf767b40caf9.png

然后执行B的构造方法,super(5);也就是调用B的父类A的构造方法,应该是到A构造的setValue()方法,同时A的成员变量value的值被赋为5,通过调试可以清楚的看到。

3564ba62ba58e45c8b68b065bf711dd6.png

接下来就是执行setValue()方法了,但是此时A类和B类都有一个setValue()方法,到底执行哪一个呢,我一开始认为是A类的setValue()方法,但是结果并不是这样的,看下调试过程。

e374228913b9ad4eec2f239c3f80b28e.png

执行的是B的setValue()方法,,,因为现在正在执行B类的构造方法,所以默认先会调用B类中的方法,如果B类中没有,才会调用其父类A中的方法。我们继续看,,,接下来到super.setValue(2 * value),即执行A类的setValue()方法,这时,A类的成员变量value应该就变成了10

9d7c50531652803f6988d62c43d5fea7.png

继续往下看,这时B类的构造方法中的super(5)就执行完了,然后就到了setValue(getValue() - 3)方法

602c99207cdc9d796a54f734d1f093e4.png

接着执行getValue()方法,首先在B类中找,但B类没有getValue()方法,所以就执行A类中的getValue()方法,A类中肯定是有的,要不然编译就不会通过

fdfd30e0128bf2bb3cb125ca0b66739b.png

然后就开始执行try、catch、finally这一块,给A的成员变量value自增,从之前的10变为11,然后直接返回value,没有捕获异常,继续到finally里面的this.setValue(value)

d4a5da82d849a2e12c7a7d85e821d6b3.png

然后这个this指的到底是A类还是B类呢,答案是B类,因为现在是在执行B的构造方法,所以this指的应该是B类,即调用B类的setValue(int value)方法

5570751f678d067c24ebe260c4716ccb.png

然后又super.setValue(2 * value);执行父类A的setValue(int value),把2 * 11作为参数传递,A类的setValue(int value)把传进来的value值赋给了A的成员变量value,变成了22。

bcaad17c0748d016331a0a69dc9def70.png

然后this.setValue(value)就执行完了,最后输出value,22

c9f36153ab2db758d8f61b9b9b02a8c6.png

到这儿getValue()方法就执行完了,但是有一点需要注意,此时的value为22,但是getValue()的返回值确是11,因为在try{ }中已经return了,所以这个方法的返回值级已经保存下来了,是11,即使finally{ }里面又对value的值做出了改变,但是getValue()的返回值是不会变的。接着继续执行B类构造方法中的setValue(getValue() - 3);getValue()是11,所以B的setValue(int value)方法的参数就为8,接着又到了super.setValue(2 * value)

ea6d11efedb3307864482d0b01b5f05d.png

调用A类的setValue(int value)方法,同时将参数赋值给A类的成员变量value,此时value变为16

8811fc7d266037da7ea61a0a9c7d90fd.png

到这儿B类的构造方法就全部执行完了,也就是new B(),然后又调用了该对象 的getValue()方法,B类没有,但是父类A有,所以,

7ee3aaf3c06bc2936f6fdbf295045ace.png

继续try{ }、catch{ }、finally{ },A类的成员变量value为16,然后value++,再返回,这时getValue()的返回值已经确定了,就是17,即使在finally中对value做出改变,其返回值不会变。然后到finally{ },又是this.setValue(value),前面已经说过了,这个this指的是B类的this,所以调用B类的setValue(int value)

7e3485f72c15cc303ee2458a38e84ccc.png

接着又是super.setValue(2 * value),调用A类的setValue(),并把2 * 17作为参数传递过去。

dbaac170f347a9029251a14edf52cb9a.png

把参数赋给A的成员变量value,这时this.setValue(value)就执行完了,此时的value为34。最后输出value。

dfb079498242285a9c3b79e9facd0f6a.png

需要注意的是,此时的getValue()方法的返回值是17,这个前面已经提到了,到这儿,整个new B().getValue()就执行完了,最后又输出了getValue的返回值,也就是17。所以整个过程执行完后的输出结果是22、34、17。。。。。。

e0917966ea4fd28fdf6a777b454a6a3d.png

这道题虽然绕了很多弯,但是我们做完后发现整体过程其实并不是很复杂,就是自类继承父类,调用方法时先是调用子类中的方法,如果没有就调用父类中的方法,还有一点就是try{ }、catch{ }、finally{ }返回值的问题,一旦try{ }中返回了某一个值,如果finally有返回值,finally中的返回值会覆盖try的返回值,如果finally没有返回值,就是try中的返回值。掌握了这些,这道题就显得很简单了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值