2011-09-26 220 views
3

我遇到了這種情況。我們有一個班可以說主要有一個私人方法打印。還有另一個Main1類,它擴展了Main類並重新定義了打印方法。由於MAIN1是MAIN1類的一個對象,我希望MAIN1打印方法被調用......Java私有方法覆蓋

public class Main { 
    public static void main(String[] args) { 
     Main main1 = new Main1(); 
     List<String> list = new ArrayList<String>(); 
     main1.print(list); 
    } 

    private void print(List<String> string) { 
     System.out.println("main"); 
    } 

} 

class Main1 extends Main { 
    public void print(List<String> string) { 
     System.out.println("main1"); 
    } 
} 

在這種情況下,當我們運行程序時,它打印「主」。它真的讓我感到困惑,因爲這種方法是私人的,甚至不是Main1類的一部分。

+0

你能澄清你的問題嗎?你爲什麼期望它不是私有的,或者是Main1的一部分? –

+0

我也很困惑,當沒有這樣的方法時('print'沒有參數),你怎麼調用main1.print();? –

+0

您已經收到正確答案。這是來自Java語言規範的相關[段落](http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.8.1)。 –

回答

13

答案並不太難:

  • main1變量的類型是MainMain1
  • ,所以你只能調用類型
  • 唯一的方法可能的方法print接受Main上的List<String>是私人的
  • 調用代碼是類Main內,因此它可以在該類

因此Main.print(List<String>)將被稱爲調用的私有方法。

注意,改變main1類型Main1將導致其他被調用print(List<String>)方法。

+1

+1:如果您將'print'設置爲非私人的,它將使用繼承。私人成員不能遵循繼承。 –

+1

我相信你錯過了這個問題的主要觀點,這就是爲什麼Main.print()不被Main1print覆蓋() –

+0

私有方法不能被重寫。這是語言規範。 – kingori

1

如果您希望能夠覆蓋您的print方法必須聲明它public

public class Main { 

    public void print(List<String> string) { 
    } 

} 

否則會打電話給你的私有方法,無需尋找在派生類中實現。

1

私有方法不被繼承,並且方法覆蓋不會在您的代碼中發生。 您可以通過在Main1.print()方法中添加@Override註釋來看到這一點。如果你把這個註解,編譯錯誤生成。在你的情況下,Main1.print()和Main.print()是不同的,並且不相互關聯(不重疊,不重載)。所以如果你將main1指定爲Main,Main.print()將被調用。如果將main1指定爲Main1,則將調用Main1.print()。

1

你的main1是一種Main類型,但用Main1實例化!沒關係,因爲它是Main的一個子類。但是,當你調用print方法時(順便說一下,它應該是main1.print(list);)它將調用Main類中的私有方法!如果將方法的可見性更改爲protected或public,在這種情況下,將調用Main1類中的print方法,因爲實例化對象的多態行爲(請記住,它畢竟是一個基於代碼的Main1對象,已經提供!)