2013-04-16 70 views
0

我很困惑,因爲我認爲這是指調用方法的當前對象。
那麼爲什麼我的對象中的實例變量x在調用繼承方法時沒有改變? 超類:爲什麼「錯誤」的實例變量被修改?

public class SuperBoss 
{ 
    int x = 50; 

    public void changeX() 
    { 
    this.x = 20; 
    } 
} 

子類:

public class Boss extends SuperBoss 
{ 
int x = 10; 
public static void main(String[] args) 
{ 
    Boss b = new Boss(); 
    b.changeX(); 
    System.out.println(b.x); //prints 10 
} 
} 

爲什麼它打印10和20不是?

+0

因爲java支持行爲覆蓋而不是屬性覆蓋。換一種說法。 Java支持方法重寫而不是變量重寫。 –

回答

5

簡短回答:因爲字段訪問在Java中不是虛擬的。


SuperBoss聲明x。

當Boss聲明x時,x不會成爲'虛擬'字段 - 它會成爲一個隱藏在超類字段中的新字段。

當你在你的Boss上調用changeX時,SuperBoss是SuperBoss中的一個方法,SuperBoss不知道Boss.x,並且訪問x不是虛擬的,所以它只訪問SuperBoss.x。

如果您需要訪問x爲虛擬的,您需要提供getX方法,並覆蓋Boss中的getX方法。現在,當SuperBoss的方法調用getX時,它會被重新路由到Boss中的getX。

+0

omg我意外地打你的答案編輯! 該死的,我希望它不會編輯它。 我的意思是評論回覆說謝謝回答。 你是什麼意思的「虛擬」? –

+0

@KacyRaye - 你沒有編輯它......他的名字左邊會有一個註釋,說「_Last編輯在..._」。 – jahroy

+1

@Kacy Raye'虛擬'意味着如果一個子類提供一個新的定義並且你有一個子類的實例,那麼即使在超類中,對該方法的任何調用都會重新路由到新的定義。非虛擬意味着超類的使用不會被重定向到新的定義。 – Patashu

1

當你在你的子類中聲明int x = 10時,你在隱藏所有人的超類變量當他們在看子類

當超類調用this.x它沒有查看子類,所以它可以獲取它自己的變量版本。

變量實際上並沒有存儲通過他們在運行時代碼的名字,所以他們重新定義這樣不起作用 - SuperBoss#x將解析爲一個符號的符號表和Boss#x將解決另一個,所以他們都依然存在,如果你知道如何看待他們。

相關問題