Java构造方法中的多态,构造方法的真正执行顺序 ------Java编程思想笔记

众所周知,调用子类的构造方法时,系统会先调用父类的构造方法。但是,当父类的构造方法调用了一个public方法A,同时子类又覆写了这个public方法A,初始化子类时,父类调用的是自己的A方法还是子类A方法呢?

答案是:子类的A方法哦。

我相信这个答案会出乎很多人意料,至少我在刚开始运行示例程序时还是难以置信的态度(ps:仔细想想其实也不难理解,毕竟在子类中,父类的A方法已经被覆写)。

咱们先跑一下示例程序,运行结果有惊喜哦。

基类Base:



public class Base {

    public void A()
    {
        System.out.println("run A() in Base"); 
    }
    public Base()
    {
        System.out.println("before run A() in Base()");
        A();
        System.out.println("after run A() in Base()");
    }
}

子类Sub:



public class Sub extends Base{
    int r = 1;
    @Override
    public void A()
    {
        System.out.println("run A() in Sub r = "+r);
    }
    public Sub(int ra) {
        r = ra;
        System.out.println("in Sub r = "+r);
    }
}

主类Main:


public class Main {

    public static void main(String[] args) {
        new Sub(5);
    }
}

运行结果:

从结果可见,创建子类对象时,系统先运行了基类Base的构造方法,这个还是符合一般常识的。但是,基类构造方法中调用了子类Sub的A方法,而且子类Sub中的成员变量r不是1,而是0(这篇博客的重点哦,赶紧记下来)!

为什么呢?

首先,基类Base的A方法已经被覆盖,不通过super关键字,常规方法基本无法调用,所以调用子类Sub的A方法才是正常的。

其次,对象的初始化过程为:

    1.将分配给对象的存储空间初始化为二进制的0.

    2.调用基类的构造方法,此时在构造方法中调用A方法,由于Sub的构造方法未执行,成员变量的赋值也尚未进行,所以r为0.

    3.按照声明顺序调用成员变量的构造方法(r此时赋值为1)

    4.调用子类的构造方法(r此时赋值为5)

没想到吧,最先执行的不是基类的构造方法,而是默认赋值哦!

总结:构造方法应该只负责初始化工作,调用的方法应该都是private方法,防止方法被子类继承修改,从而造成无法预知的错误。

参考文献

[1].Java编程思想(第4版).埃尔克.北京:机械工业出版社,2007.6:162-164

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值