2013-03-24 74 views
3

我正在閱讀「Thinking in Java」並且有疑問。在「重用類」一章中,「最終和私有」一節中,它指出私有方法不能被覆蓋。不過,我在機器上試了一下。它實際上可以被覆蓋。覆蓋私有方法

下面是代碼

class Amphibian { 
    private void print() { System.out.println("in Amphibian"); } 
} 

public class Frog extends Amphibian { 
    public void print(System.out.println("in Frog"); } 

    public static void main(String[] args) { 
      Frog f = new Frog(); 
      f.print(); 
    } 
} 
+1

你的代碼實際上並沒有編譯。 – millimoose 2013-03-24 18:55:42

+0

它編譯在我的機器上。 – NoviceCai 2013-03-24 19:12:29

+0

然後代碼「在您的機器上」與您的問題中的代碼不相同,因爲該代碼明顯被破壞。 – millimoose 2013-03-24 19:17:54

回答

12

你沒有覆蓋它,你只是躲在與具有相同名稱的新方法。

如果您沒有創建新的print()方法,那麼您的Frog類將不會有一個。

+2

確切地說,使用'@ Override'註釋,你會得到一個錯誤:) – 2013-03-24 18:53:37

+1

好的。謝謝。所以沒有@override,它只是隱藏定義而不是覆蓋它。 – NoviceCai 2013-03-24 18:54:51

+0

是的,確切地說。 '@ Override'將檢查你是否實際覆蓋了一個繼承的方法。如果你輸錯了,或者如果沒有任何方法,你會覆蓋,它會標記爲錯誤 – 2013-03-24 18:56:50

4

爲了說明重寫和隱藏之間的差異,可以這樣考慮:

class Amphibian { 
    private void print() { System.out.println("in Amphibian"); } 
    public void callPrint() { 
     /* 
     * This will DIRECTLY call Amphibian.print(), regardless of whether the 
     * current object is an instance of Amphibian or Frog, and whether the 
     * latter hides the method or not. 
     */ 
     print(); // this call is bound early 
    } 
} 

class Frog extends Amphibian { 
    public void print() { System.out.println("in Frog"); } 
    public static void main(String[] args) { 
     Frog f = new Frog(); 
     f.callPrint(); // => in Amphibian 

     // this call is bound late 
     f.print(); // => in Frog 
    } 
} 

的「首要」(即隱藏)方法不會被調用,所述一個在父類中一樣。這意味着它不是真正的覆蓋。

+0

這是一個小技巧。如果您使用兩棲動物私密打印,則無法覆蓋它。但是,如果你公開,不管你是否使用@Override,它總是會在Frog中被覆蓋。 – NoviceCai 2013-03-24 19:05:36

+0

我試着讓你的代碼公開,並且把@Override放在Frog的print前面。我得到了同樣的結果。 – NoviceCai 2013-03-24 19:06:22

+1

@NoviceCai沒有涉及的技巧,這就是Java的工作方式。 '@ Override'不會改變代碼的語義,如果註釋的方法沒有覆蓋任何東西,它只會讓Java編譯器給你一個錯誤。註釋的目的是捕捉錯誤,而不是在基類中重寫一個方法。任何*虛擬*方法都可以並且將被另一種在子類中具有兼容簽名的方法覆蓋。 IIRC,在Java中,每個非'private'方法都是虛擬的,不管其他方法如何註解。 – millimoose 2013-03-24 19:21:11

0

您可以簡單地在subclass中編寫private方法,但不會被覆蓋。但它仍然遵循其在覆蓋

使用如果您在superclass方法更廣泛地access modifier(默認情況下,保護公衆)當subclass's方法是私有的,然後編譯器顯示錯誤的訪問修飾符規則。它遵循覆蓋規則,但不會實際覆蓋。