2017-07-19 166 views
-1
public class A { 
    String bar = "A.bar"; 

    A() { foo(); } 

    public void foo() { 
    System.out.println("A.foo(): bar = " + bar); 
    } 
} 

public class B extends A { 
    String bar = "B.bar"; 

    B(){ foo(); } 

    public void foo(){ 
     System.out.println("B.foo(): bar = " + bar); 
    } 
} 

public class C { 
    public static void main(String[] args){ 
     A a = new B(); 
     System.out.println("a.bar = " + a.bar); 
     a.foo(); 
    } 
} 

爲什麼第一個輸出有bar = null? 是否因爲在創建類B之前調用了B.foo()?如果是,那麼怎麼來B.foo()可以被調用? 還是因爲B.foo()中的字段欄試圖從A獲取欄字段,但無法訪問它?調用超類構造函數的子類方法

我的問題是不同的一個鏈接,我不問有關呼叫順序,我問爲什麼第一個輸出爲空?另一個問題不是關於字段或空變量。

我不明白,在B.foo酒吧變量如何爲null,如果在A和B中

+1

的可能的複製[在什麼順序來在Java中的靜態/實例初始化語句塊運行?](https://stackoverflow.com/questions/2007666/in-what-order-do-static-instance-initializer-blocks-in-java-run) – Tom

+0

請將代碼粘貼爲* text *而不是圖片。 –

回答

0

定義起初,我想告訴你的是,可變在類一個完全不同於其他變量barB

可能是你想,他們是這樣的一個變量:

public class B extends A{ 

public B(){ 
     bar = "B.bar";´ 
    foo(); 
} 
void foo(){ 
    System.out.println("B.foo bar ="+ bar); 
} 

}

,你將有結果:

B.foo bar =A.bar 
B.foo bar =B.bar 
a.bar=B.bar 
B.foo bar =B.bar 

時不告訴是請,並且我還會爲您描述您的特殊情況(爲什麼bar = null

0

的原因,第一個是打印是B.foo(): bar=null因爲當你調用線A a = new B();正在發生的事情是,你創建B類型的對象,這就要求B類型的對象的構造函數。但是,該構造函數對構造函數A的「隱藏」super調用。問題是B類尚未創建(您現在正在創建類A的過程中),因此它們的參數(例如bar)未初始化,這意味着它們被分配了null值。由於對動態功能的調用是通過動態調度來完成的,因此您仍然可以獲得B.foo():,因此調用B的函數foo。只有在調用A的構造函數後,才能調用B的構造函數,然後初始化B的變量 - 包括bar

+0

好吧,我會同意,如果富是靜態的,但它不是如此,我不明白它如何可以調用foo如果沒有B的實例。 – Raz

+0

@Raz因爲你不初始化方法。該方法屬於「B」類。動態調度機制試圖調用「A」的'foo',但是當它「看到」對象的動態類型是'B'類型時,它只是調用'B'的'foo'方法。 – Mickey

+0

我試圖看看在類已經初始化之前是否可以調用類的方法。和我發現這個問題https://stackoverflow.com/questions/2394205/can-i-use-methods-of-a-class-without-instantiating-this-class其中說,你不能 – Raz

0

您好,這是您的代碼行由行的行程 enter image description here

相關問題