繼承是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
得出結論以下:
一、若子類覆蓋了某方法,則子類引用調用子類從新定義的新方法
二、若子類未覆蓋某方法,則子類引用調用父類自己的舊方法
三、若子類覆蓋了某屬性,則子類引用調用子類從新定義的新屬性
四、若子類未覆蓋某屬性,則子類引用調用父類自己的舊屬性
五、子類引用能夠訪問子類新定義的方法