java中子类继承父类,程序运行顺序的深入分析
发布时间:2020-12-14 14:19:35 所属栏目:Java 来源:网络整理
导读:我们经常在项目中使用继承,但是往往不太明白,程序运行的顺序以及原理,尤其是使用上转型对象的时候,以及父类子类中都有static变量和方法时,不知道先运行谁。我也是写了一个例子。总结了一下。 复制代码 代码如下: 父类: public class TestStatic { publi
我们经常在项目中使用继承,但是往往不太明白,程序运行的顺序以及原理,尤其是使用上转型对象的时候,以及父类子类中都有static变量和方法时,不知道先运行谁。我也是写了一个例子。总结了一下。 复制代码 代码如下: 父类: public class TestStatic { public static String name="china"; { System.out.println("========方法体========"); } static{ name="England"; System.out.println("========静态程序块======"); } TestStatic(){ System.out.println("=========构造方法========"); } public static void main(String[] args){ System.out.println("========主方法========"+name); } public void test(){ System.out.println("========测试方法========="); } } 子类: public class TestExtendStatic extends TestStatic{ //public static String name="HUBEI"; { System.out.println("========无名称方法体========"); } static{ //name="SUIZHOU"; System.out.println("========子类静态程序块======"); } TestExtendStatic(){ System.out.println("=========子类构造方法========"); } public void test(){ System.out.println("========子类测试方法========="); } public static void main(String[] args){ System.out.println("========子类主方法========"+name); TestStatic ts = new TestExtendStatic();// 上转型对象 ts.test(); } } 输出如下: ========静态程序块====== :父类static程序块 ========子类静态程序块====== :子类static程序块 【不是静态方法】 ========子类主方法========England :子类主方法 ========方法体======== :父类中非静态代码块 =========构造方法======== :父类构造方法 ========无名称方法体======== :子类中非静态代码块 =========子类构造方法======== :子类构造方法 ========子类测试方法========= :子类测试方法 执行顺序: 父类静态变量以及静态程序块 --- 子类的静态变量以及静态程序块 --- 父类非静态代码块 --- 父类中构造方法 --- 子类中非静态代码块 --- 子类中构造方法 --- 接下来才是 对象调用的方 法。 只要是用new 创建对象,分配了内存空间,不管是将引用赋给上转型对象,还是赋给子类对象,上面方法都必须执行。 即:TestStatic ts = new TestExtendStatic();// 上转型对象 TestExtendStatic ts = new TestExtendStatic();// 子类对象 上面加粗程序都会执行。 上面程序中 ts.test(); ts作为上转型对象调用的是 子类继承的父类中的方法,因为test()在子类中被重写了,所以输出的为子类中的语句。 如果将子类中 main 方法该成如下: 复制代码 代码如下: public static void main(String[] args){ System.out.println("========子类主方法========"+name); TestStatic ts = new TestExtendStatic(); ts.test(); System.out.println("-------------------------"); ts = new TestExtendStatic(); ts.test(); } 输出: ========静态程序块====== 父类中静态程序块 ========子类静态程序块====== 子类中静态程序块 ========子类主方法========England 子类中主方法 ========方法体======== 父类中非静态代码块 =========构造方法======== 父类中构造方法 ========无名称方法体======== 子类中非静态程序块 =========子类构造方法======== 子类中构造方法 ========子类测试方法========= 对象具体调用的方法 ------------------------- 静态变量以及程序块只执行一次 ========方法体======== 父类中非静态代码块 =========构造方法======== 父类中构造方法 ========无名称方法体======== 子类中非静态代码块 =========子类构造方法======== 子类中构造方法 ========子类测试方法========= 如果将子类主方法 中更改为: 复制代码 代码如下: TestStatic ts = new TestStatic ();// 运用父类构造方法创建 ts.test(); 输出为: ========静态程序块====== 父类静态程序块 ========子类静态程序块====== 子类静态程序块 【因为程序在子类中运行的,所以子类的静态程序块必须运行】 ========方法体======== 父类非静态程序块 =========构造方法======== 父类构造方法 ========测试方法========= 父类具体方法test() 如果将上述代码放到父类中,就不会加载子类 静态程序块了。 通过上面 我们还可以发现,静态程序块运行 是在主方法之前,非静态程序块运行是在主方法之后。 我在父类中 主方法中创建一个对象 调用test(),运行的结果: ========静态程序块====== 静态代码块 ===main== ========方法体======== 非静态代码块 =========构造方法======== 构造方法 ========测试方法========= 总结: 程序运行时(一个类中),会第一时间加载运行静态代码块,一旦创建对象,就会执行非静态代码块以及无参构造方法。 而在继承中,程序运行时 会先加载父类中静态代码块 然后加载本身静态代码块,一旦创建对象(运用子类构造方法创建),就会调用 父类非静态代码块,父类构造方法,然后就是本身 非静态代码块,本身构造方法。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |