继承是java实现多态的一个重要元素之一,本文主要是自我学习了解java继承中父类和子类的关系。下面看父类和子类的源码java
父类:ide
public class Parent { //公有属性 private int a = 5; //公有属性b public int b = 10; //公有属性c public int c = 10; //静态代码块 static { System.out.println("parent static"); } //非静态代码块 { System.out.println("Non-static block from Parent"); } //构造方法 public Parent(){ System.out.println("Parent init constructor"); } //获取私有属性a的值 public int getA(){ return a; } //公有方法 public void say(){ System.out.println("hello i am parent"); } }
子类:函数
public class Son extends Parent { //子类私有属性 private int a = 6; //子类覆盖了父类的属性b public int b = 20; //子类的静态代码块 static { System.out.println("Son static"); } //子类非静态代码块 { System.out.println("Non-static block from Son"); } //子类的构造方法 public Son(){ // super(); System.out.println("Son constructor"); } //子类覆盖了父类的say方法 @Override public void say() { System.out.println("I am son"); } public int getA(){ return a; } //子类新定义的方法 public int getH(){ return 5; } }
用例1(父类引用指向子类对象)测试执行顺序:学习
本例主要测试父类和子类中静态代码块、非静态代码块、构造函数的执行顺序测试
public static void main(String[] args) { Parent parent = new Son(); } //输出结果 parent static Son static Non-static block from Parent Parent init constructor Non-static block from Son Son constructor
从运行结果能够看出执行顺序:父类静态代码块-子类静态块-父类非静态块-父类构造方法-子类非静态代码块-子类构造方法spa
所以能够得出结论:对于普通类代码的执行顺序为【静态代码块-非静态代码块-构造方法】;对于父子类继承关系的类, 不管是父类引用指向子类对象仍是子类引用指向自身对象代码的执行顺序都为【父类静态代码块-子类静态块-父类非静态块-父类构造方法-子类非静态代码块-子类构造方法】,总之先执行父类的静态代码块而后紧跟着执行子类的静态代码块,其余的保持不变code
注意:若是main方法在子类中时即使是父类引用指向父类对象也会执行子类中的静态 代码块,子类中的其余则不执行对象
用例2(父类引用指向子类对象)测试父子类对象中属性方法的执行状况:继承
public class Test { public static void main(String[] args) { Parent parent = new Son(); parent.say(); System.out.println(parent.getA()); System.out.println(parent.b); System.out.println(parent.c); } } //测试结果,前面已经分析过一些,主要看后四项 parent static Son static Non-static block from Parent Parent init constructor Non-static block from Son Son constructor I am son 6 10 10
得出结论以下:get
一、若子类覆盖了某方法,则父类引用调用子类从新定义的新方法
二、若子类未覆盖某方法,则父类引用调用父类自己的旧方法
三、若子类覆盖了某属性,但父类引用仍调用父类自己的旧属性
四、若子类未覆盖某属性,则父类引用调用父类自己的旧属性
五、父类引用不能访问子类新定义的方法
用例3(子类引用指向自身对象)测试父子类对象中属性方法的执行状况:
public class Test { public static void main(String[] args) { Son parent = new Son(); parent.say(); System.out.println(parent.getA()); System.out.println(parent.b); System.out.println(parent.c); System.out.println(parent.getH()); } } //执行结果 parent static Son static Non-static block from Parent Parent init constructor Non-static block from Son Son constructor I am son 6 20 10 3
得出结论以下:
一、若子类覆盖了某方法,则子类引用调用子类从新定义的新方法
二、若子类未覆盖某方法,则子类引用调用父类自己的旧方法
三、若子类覆盖了某属性,则子类引用调用子类从新定义的新属性
四、若子类未覆盖某属性,则子类引用调用父类自己的旧属性
五、子类引用能够访问子类新定义的方法