子类的成员执行顺序问题解析"/>
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", "构造器");}@Overridevoid 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了"。因此又得出一个结论“静态方法可以继承,但不能重写”
更多推荐
java中有关父类和子类的成员执行顺序问题解析
发布评论