? ? ?構造方法的調用順序:子類構造器中,JVM會自動的先調用父類的構造方法,然后再執行子類構造方法。在JVM自動調用父類構造方法的時候,會完成父類中擁有的成員變量的值的初始化操作,此時子類的成員變量并未初始化,java中基本類型都會使用JVM給定的默認值(如int為0),只有當父類構造方法調用結束,并到執行子類構造器時才會進行子類成員變量的初始化過程。
? ? ?動態綁定:對于非private、static、final修飾的方法,JVM是在運行期間,用函數指針指向實習對象類型的方法。比如,子類重寫了父類的A方法,使用父類Upper的引用upper指向了子類Sub對象,然后upper.A(),實際調用的類Sub中A方法。我是這樣理解的,子類和父類中都有方法A,并且子類是通過重寫的方式實現了A,所以子類對象原本Upper中指向方法A的指針和Sub類中指向A的指針是通過同一個函數指針,兩次賦值。就是指針point值被替換了,不是把父類的函數指針隱藏了,而是相當于兩次給指針賦值,第一次使用父類A方法的指針賦給point,第二次使用子類A方法的指針賦給point(以上純屬自己的理解,如果不真確歡迎給位老師指點,因為自己還是剛入行)。所以每一父類的方法的地址被子類方法的地址替換了。
demo:
Upper Code:
1 package com.hq.dynamicBind; 2 3 public class Upper { 4 5 private int i = 1; 6 7 public void print(){ 8 System.out.println("i="+i); 9 } 10 11 public Upper(){ 12 System.out.println("父類構造函數開始"); 13 System.out.println("i="+i); 14 print(); 15 System.out.println("父類構造函數嗲用print()結束"); 16 i = 30; 17 } 18 }
Sub Code:
1 package com.hq.dynamicBind; 2 3 public class Sub extends Upper { 4 5 private int j = 20; 6 7 public void print() { 8 System.out.println("j="+j); 9 } 10 11 public Sub(){ 12 System.out.println("成員變量j="+j); 13 print(); 14 j = 40; 15 } 16 17 }
Client Code:
1 package com.hq.dynamicBind; 2 3 public class Client { 4 5 public static void main(String[] args ){ 6 new Sub().print(); 7 } 8 }
執行結果:
父類構造函數開始
i=1
父類構造函數嗲用print()結束
成員變量j=20
j=20
j=40
?