2010-03-17 75 views

回答

23

因爲繼承旨在修改行爲。行爲通過方法暴露,這就是爲什麼他們可以被覆蓋。

字段不是行爲而是狀態。你不需要修改它,也不需要修改超類所使用的私有方法。它們的目的是讓超類來完成它的工作。

28

你可以隱藏一個字段,但不是覆蓋它。

隱藏意味着一個字段將有一個不同的值,具體取決於它訪問哪個類。子類中的字段將「隱藏」超類中的字段,但都存在。

這是一個非常不好的做法隱藏的領域,但工作原理:

public class HideField { 

    public static class A 
    { 
     String name = "a"; 

     public void doIt1() { System.out.println(name); }; 
     public void doIt2() { System.out.println(name); }; 
    } 

    public static class B extends A 
    { 
     String name = "b"; 

     public void doIt2() { System.out.println(name); }; 
    } 

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

     a.doIt1(); // print a 
     b.doIt1(); // print a 
     a.doIt2(); // print a 
     b.doIt2(); // print b <-- B.name hides A.name 
    } 
} 

根據是否該方法AB重寫,現場訪問。

千萬別這麼做!這永遠不會解決您的問題,並創建與繼承有關的非常微妙的錯誤。

+0

哦,多個upvotes的強制性建議,不要做這個。這就像一個邪惡的霸主轉變成一條蛇......它從來沒有幫助。 – 2013-09-26 13:03:14

+0

有一些微妙的原因可能會導致您特別喜歡:特別是使用通過專門使用超級或子類名訪問的靜態類字段。 「永不」永遠不是一件好事情;) – RichieHH 2014-05-14 15:20:12

+0

使用靜態是完全另一回事,Oracle對@ewernli有相同的建議:http://docs.oracle.com/javase/tutorial/java/IandI/hidevariables.html – MengT 2014-10-03 08:08:27

1

因爲:

  • 它可能會破壞parent class代碼。例如,請考慮下面的代碼(什麼是在下面的代碼行obB.getInt();的行爲如果實例變量覆蓋是允許的):

    class A 
    { 
        int aInt; 
    
        public int getInt() 
        { 
         return aInt; 
        } 
    } 
    
    class B extends A 
    { 
        int aInt; 
    
        public int getInt2() 
        { 
         return aInt; 
        } 
    
        public static void main(String[] args) 
        { 
         B obB = new B(); 
    
         //What would be behavior in following line if, 
         //instance variables overriding is allowed 
         obB.getInt(); 
        } 
    } 
    
  • 這不是邏輯因爲child class應該有/反映所有行爲parent class

所以,你只能隱藏child class繼承的方法/變量,但不能override

以下是Java doc from Oracle提取指定什麼操作可以執行/從child class期待:

您可以使用繼承的成員是,取代他們,隱藏起來,或者用新的成員來補充其不足:

  • 繼承字段可以直接使用,就像任何其他字段一樣。
  • 您可以在子類中聲明一個與超類中相同名稱的字段,從而隱藏它(不推薦)。