2012-02-21 92 views
0

請考慮以下代碼類。何時調用構造函數創建對象




    public class A 
    { 
     public A() 
     { 
      callCreation(); 
     } 

     protected void callCreation() 
     { 
      System.out.println("A Created!!"); 
     } 
    } 




    public class B extends A 
    { 
     protected void callCreation() 
     { 
      System.out.println("B Created!!"); 
     } 
    } 


    public class C extends B 
    { 
     protected void callCreation() 
     { 
      System.out.println("C Created!!"); 
     } 

     public static void main(String[] args) 
     { 
      A a = new A(); 
      A b = new B(); 
      A c = new C(); 
     } 
    } 

運行C類的輸出如下。

 
A Created!! 
B Created!! 
C Created!! 

在輸出

A Created!!
第一輸出線被隱式要求在所述callCreation()方法之前打印,因爲當A類的構造函數被調用時,它調用超類的構造函數(java.lang.Object中) A類的構造函數。 B和C類也是如此。在這種情況下,當調用B的構造函數時,調用流應該是典型的:B的構造函數 - > A的構造函數 - > java.lang.Object的構造函數 - >返回A的callCreation()方法來完成調用A的構造函數。如果是這樣,打印的值是如何被打印的,而不打印超類的值?所以問題是'什麼時候創建了一個類的對象?換句話說,只有在構造器完成調用/初始化其內部的所有元素後,才能創建類的對象。如果是的話,如何從一個子類而不是從父類調用一個方法?

回答

4

callCreation方法在B和C 覆蓋從A的方法因此,當調用該方法在構造函數中的B和C的實現將運行,即使B和C的構造函數都沒有執行尚未。這是可能的,因爲構造函數實際上不創建對象,而是在JVM創建它之後的某些時刻調用初始化

通常,由於這個原因,調用可以從構造函數重寫的方法是非常糟糕的主意。 B或C中的方法可能會假定構造函數和對象初始值設定項已經運行,並從字段中讀取一個意外的值。例如,以下結果是打印"B Created!! null",因爲該字段仍未分配其值。

public class B extends A 
{ 
    final String msg = "Yes!"; 

    protected void callCreation() 
    { 
     System.out.println("B Created!! "+msg); 
    } 
} 
+0

+1正確 - 它總是從相同的構造函數中調用。唯一的區別是通話去的地方。 – 2012-02-21 17:17:07

+0

不是jvm需要一個對象來調用它的方法嗎?請在下面的答案中找到我的評論。 – user1223879 2012-02-21 17:31:56

+0

是的;實際上它也需要一個運行構造函數*的對象。該對象在構造函數執行前很久就存在。 – Joni 2012-02-21 17:33:44

0

在這種方式思維使得它更明顯: 正在創建乙類型的對象時超級()關鍵字調用的構造方法, 然後在構造函數「this.callCreation()」被執行時,它指的是當前對象是B,所以調用對應於當前對象(B)的callCreation。 相同的過程是爲C.完成

公共類A {

public A() { 
    this.callCreation(); 
} 

protected void callCreation() { 
    System.out.println("A Created!!"); 
} 

}

類B擴展A {

public B() { 
    super(); 
} 

protected void callCreation() { 
    System.out.println("B Created!!"); 
} 

}

C類延伸乙{

public C() { 
    super(); 
} 

protected void callCreation() { 
    System.out.println("C Created!!"); 
} 

public static void main(String[] args) { 

     A a = new A(); 
     A b = new B(); 
     A c = new C(); 

} 

}

相關問題