2013-01-01 15 views
6

可能重複:
The concept of shadowingJava在上傳時如何處理字段?

我感到困惑的是如何類的字段向上轉型過程中的Java處理。例如:

class SuperClass 
{ 
    String myString = "String in SuperClass"; 

    public void myMethod() 
    { 
     System.out.println("Method in SuperClass"); 
    } 
} 

class SubClass extends SuperClass 
{ 
    String myString = "String in SubClass"; 

    public void myMethod() 
    { 
     System.out.println("Method in SubClass"); 
    } 
} 

class Question 
{ 
    public static void main(String[] args) 
    { 
     SuperClass test = new SubClass(); 
      // object test is an instance of SubClass 
      // but I am telling the compiler to treat it as SuperClass 

     test.myMethod(); 
     System.out.println(test.myString); 

    } 
} 

輸出:

Method in SubClass 
String in SuperClass //Why is "String in SubClass" not used? 

當我創建一個對象test它是​​類的一個實例;但是,我正在告訴編譯器將其視爲SuperClass。關於方法的工作,一切都很清楚:如果爲SuperClass定義了給定方法,我將只能使用​​的方法。

但是,我爲什麼在嘗試訪問testmyString時爲什麼使用SuperClass的字段時丟失了。由於test是​​的一個實例,因此我期望使用​​中定義的myString,爲什麼不會發生這種情況?我錯過了什麼?

我知道我可以通過使用this運算符來訪問,​​的myString。例如,我可以在父類定義printMyString方法,並與

public void printMyString() 
{ 
    System.out.println(this.myString); 
} 

在​​覆蓋它,所以我的問題主要是關於怎麼來的SuperClass領域中test使用。也許我錯過了一些明顯的東西?

我試圖尋找答案,我發現最接近的主題是Upcasting in Java and two separate object properties,雖然很有幫助,但沒有回答我的問題。

先謝謝你

+0

很好的問題@Akavall –

回答

7

屬性不能重載像方法。

test.myMethod(); 

這裏方法調用依賴於類型實際對象的。這裏的對象是類型​​,所以調用​​的方法。

test.myString 

當訪問屬性,這取決於類型的參考變量的。這裏的參考變量,即test的類型是SuperClass,因此訪問來自SuperClass的屬性。

你在找什麼是class variable hiding/shadowing

+0

尼斯鏈接,謝謝。的關鍵部分是:「當在子類中的實例變量具有相同的名稱作爲一個超類的一個實例變量,則實例變量選擇在一個引用類型的類。」 – Akavall

+0

@Aavall:雅你點了:) – xyz

3

字段在Java中是只是隱而不實際覆蓋(這並不意味着,儘管嘗試此,我們將得到一個編譯時錯誤,而不是他們沒有真正意義上覆蓋)。

重寫裝置的部件應當基於運行時間 類型基於聲明的類型的對象,而不是被調用。

但在Java領域的結合始終是靜態的,因此它的基礎上,聲明類型只有對象的引用的。

在您給出的示例中,通過在類​​中聲明名稱爲'myString'的類變量,您可以隱藏它將從其超類SuperClass繼承的類變量,其名稱爲'myString'。

Java語言規範:

如果類聲明的字段具有一定的名稱,則 聲明的那場被稱爲隱藏字段的任何和所有可訪問 聲明與超同名,並且該類的超接口爲 。

隱藏字段可以通過使用限定名,如果它是靜態的,或者通過使用包含關鍵字super或流延到一個超類類型的字段訪問表達式來訪問。