天天看點

Java中方法的重寫與成員變量的隐藏

這篇文章讨論了Java面向對象概念中一個基本的概念–Field Hiding(隐藏成員變量)

在讨論這個問題之前,我們看一段特别特别簡單的代碼,請問一下方法的資料結果是什麼?

public class FieldOverriding { 
 
    public static void main(String[] args) { 
        Sub c1 = new Sub(); 
        System.out.println(" c1.s : " + c1.s); 
        System.out.println(" c1.say : " + c1.say()); 
 
        Super c2 = new Sub(); 
        System.out.println(" c2.s : " + c2.s); 
        System.out.println(" c2.say : " + c2.say()); 
    } 
} 
 
class Super { 
    String s = "Super"; 
 
    String say(){ 
        return "hello Super"; 
    } 
} 
 
class Sub extends Super { 
    String s = "Sub"; 
 
    String say(){ 
        return "hello Sub"; 
    } 
}       

輸出結果:

c1.s : Sub 
c1.say : hello Sub 
c2.s : Super 
c2.say : hello Sub       

和你想的一樣嗎,如果一樣的話,那就不用繼續往下看了。因為這個本來就不難,知道了就行。

Java中的重寫

在深入了解Java中的重寫和重載中我們介紹過:

在Java的子類與父類中有兩個名稱、參數清單都相同的方法的情況。由于他們具有相同的方法簽名,是以子類中的新方法将覆寫父類中原有的方法。

正式因為Java在繼承中有方法的重寫,是以,這也展現了Java的動态多态性。

成員變量在Java中能夠被重寫麼?

上面的Java的重寫介紹中明确的說了,重寫,指的是方法。并沒有提到成員變量。通過上面的例子,其實我們也可以發現,成員變量并沒有被重寫。

是以,Java中,成員變量并不會被重寫。這裡就有另外一個詞:隐藏。

Java中成員變量的隐藏

Java文檔中對隐藏域的定義:

Within a class, a field that has the same name as a field in the superclass hides the superclass’s field, even if their types are different. Within the subclass, the field in the superclass cannot be referenced by its simple name. Instead, the field must be accessed through super. Generally speaking, we don’t recommend hiding fields as it makes code difficult to read.

翻譯成中文:

在一個類中,子類中的成員變量如果和父類中的成員變量同名,那麼即使他們類型不一樣,隻要名字一樣。父類中的成員變量都會被隐藏。在子類中,父類的成員變量不能被簡單的用引用來通路。而是,必須從父類的引用獲得父類被隐藏的成員變量,一般來說,我們不推薦隐藏成員變量,因為這樣會使代碼變得難以閱讀。

其實,簡單來說,就是子類不會去重寫覆寫父類的成員變量,是以成員變量的通路不能像方法一樣使用多态去通路。

如何通路被隐藏的成員變量

其實,通過前面的例子,和剛剛關于成員變量的介紹,其實你已經知道了如何通路被隐藏的成員變量。 就是使用父類的引用來通路成員變量,如Super c2 = new Sub(); System.out.println(" c2.s : " + c2.s);。或者使用System.out.println(((Super)c1).s);。