Java对象向上转型多态的运用

发现一道有趣的试题,可以加深对多态实例化子类调用方法的理解,如下:

class Test {
    public static void main(String[] args) {
        System.out.println(new B().getValue());
    }
    static class A {
        protected int value;
        public A (int v) {
            setValue(v);
        }
        public void setValue(int value) {
            this.value= value;
        }
        public int getValue() {
            try {
                value ++;
                return value;
            } finally {
                this.setValue(value);
                System.out.println(value);
            }
        }
    }
    static class B extends A {
        public B () {
            super(5);
            setValue(getValue()- 3);
        }
        public void setValue(int value) {
            super.setValue(2 * value);
        }
    }
}

        该题主要考的是对面向对象多态的理解,本题中最主要的是遵循一个原则:调用方法都是实例化后的子类的重写方法,除非明确指定super.xx或者子类没有该方法时,才会调用父类的同名方法。

        在这道题中,首先构造了一个new B()的B类实例,进入B类中,构造器中super(5)调用父类带参构造器,执行setValue(v);,注意!这里的调用者为B类【遵循调用方法都是实例化后的子类的重写方法原则】,进入B类的setValue方法,B类该方法中明确指定调用父类的方法:super.setValue(2 * value) => 2*5=10传入进去,此时父类value值为10

        紧接着,B类继续执行setValue(getValue()- 3);,首先执行getValue()方法,在该方法中:

        1.首先value++,即10+1=11,但因为try...finally是在方法体中,后面还有finally,要等finally执行完后,才会return返回该值(finally执行操作对value值的改变不会影响到return返回的value值)。

        2.在finally中,调用了setValue方法,注意!这里的调用者仍然是B类【遵循调用方法都是实例化后的子类的重写方法原则,并且这里使用了this关键字,指定了调用当前对象的方法】。

        3.子类的setValue方法中,同上,明确指定调用父类的方法 => 11*2=22,即父类的value值为22

        4.因此,finally这里输出22,然后return执行,返回value值11(给到方法,同时父类A的value值也为11)。

        执行完getValue方法,回过头继续执行setValue(getValue()- 3),通过上面得知,getValue的返回值为11,即11-3=8,再调用B类的setValue方法 => 2*8=16传入父类的setValue方法中,此时父类的value值为16.

        接下来执行new B().getValue()中的getValue()方法,由于B类没有getValue()方法,因此进入父类的该方法中:

  1. value值为16
  2. 进入getValue方法后,首先执行value++,即16+1=17,等待finally执行完后return返回该值
  3. 在finally中,调用setValue()方法,调用者依然为B类对象【遵循调用方法都是实例化后的子类的重写方法原则,并且这里使用了this关键字,指定了调用当前对象的方法】
  4. 进入B类的setValue()中,同上,明确指定调用父类的方法 => 17*2=34,即父类的value值为34,因此,finally这里再次输出34,return value值为17

        最后,System.out.println(new B().getValue());会将getValue()的返回值打印出来,即输出17.

        最终结果输出:22  34  17

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值