java中有关父类和子类的成员执行顺序问题解析

前言

最近看到这么个问题,大约就是父类子类中好多成员、方法,有的静态有的非静态,实例化一个或者多态调用的时候具体怎么个执行顺序,本以为自己知道的,结果越绕越糊涂,在此记录学习过程。

结论

如果实例化一个子类对象

Chlid mChlid = new Chlid();

执行顺序如下

1、父类静态变量和静态代码块(先声明的先执行);

因为有继承关系,所以先加载父类,加载过程中执行了静态变量和静态代码块
2、子类静态变量和静态代码块(先声明的先执行);

其次才加载子类,执行子类的静态变量和静态代码块
3、父类的变量和代码块(先声明的先执行);

构造方法前先声明所有非静态成员
4、父类的构造函数;

子类构造方法中必须显示或隐式调用父类构造方法
5、子类的变量和代码块(先声明的先执行);
6、子类的构造函数。

父静子静,父非静父构,子非静子构

论证

父类

public class Parent {
    static int age = 30;
    Temp mTemp = new Temp("FF");
    String name = "Pappy";

    static {
        Log.d("FF", "静态代码块");
    }

    public Parent() {
        Log.d("FF", "构造器");
    }

    void speak(){
        Log.d("FF", "我是"+ name);
    }

    static void describe(){
        Log.d("FF", "我" + age + "了");
    }
}

子类

public class Chlid extends Parent {
    static int age = 17;
    Temp mTemp = new Temp("CC");//为体现非静态成员
    String name = "Baby";

    static {
        Log.d("CC", "静态代码块");
    }


    public Chlid() {
        Log.d("CC", "构造器");
    }

    @Override
    void speak() {
        Log.d("CC", "我是"+ name);
    }

    static void describe(){
        Log.d("CC", "我" + age + "了");
    }
}

temp

public class Temp {
    public Temp(String temp) {
        Log.e(temp, "非静态成员");
    }
}

 测试类

public class TestFC {
    Chlid mChlid = new Chlid();
    Parent mParent = new Parent();
    Parent mPC = new Chlid();
    //报错ClassCastException
//    Chlid mCP = (Chlid) new Parent();

    public void start1(){
        Log.e("Test","**********");
        Log.e("Test","父引-父象");
        mParent.speak();
        mParent.describe();
    }

    public void start2(){
        Log.e("Test","**********");
        Log.e("Test","子引-子象");
        mChlid.speak();
        mChlid.describe();
    }

    public void start3(){
        Log.e("Test","**********");
        Log.e("Test","父引-子象");
        mPC.speak();
        mPC.describe();
    }

}

调用测试

TestFC testFC = new TestFC();
testFC.start1();
testFC.start2();
testFC.start3();

log结果

总结

以上测试用例基本都涵盖这方面所有内容了,现在来分析

1.因为TestFC先声明实例化Child,从log前几段可以看出,执行顺序确实是"父静子静,父非静父构,子非静子构",之后因为已经加载了两个类,因此静态代码块都不执行了,但是只要执行子类构造方法,必先调用父类构造方法。

2.多态问题看最后一组log可以看出,父类引用指向子类对象时,调用非静态成员是子类自己的,因为对象就是子类,但是静态成员却还是父类的,其中如果把子类中的静态方法去掉,第二组log"子引-子象"中会显示"我30了"。因此又得出一个结论“静态方法可以继承,但不能重写

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值