2014-11-01 31 views
1

考慮下面的代碼:超類的私有方法執行的子類參考

父類:

package poc.poc; 

public class SuperClass { 

    private void method() { 
    System.out.println("SuperClass!"); 
    } 

    public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    SuperClass s = new SubClass(); 
    s.method(); 
    } 

} 

亞綱:

package poc.poc; 

public class SubClass extends SuperClass { 
    public void method() { 
    System.out.println("Subclass!"); 
    } 
} 

當我運行的SuperClass的主要方法,我希望得到某種例外,但實際上是將運行SuperClass中的代碼,而不是​​中的代碼,並因此在子類實例上運行超類類型的實例方法。

爲什麼會發生這種情況?編輯:這不違反封裝嗎?

P.S.當更改爲受保護的修飾符而不是私有修飾符時,多態性開始啓動,我們又回到了我所稱的「預期行爲」

+2

這是因爲私人方法是在範圍內,因爲你在同一個文件。如果你在第三個文件中創建'main',你的代碼將不能編譯。 – 2014-11-01 13:37:32

+1

在SubClass的''method'上放置一個@ @ Override'註解,你就會明白。 – Daniel 2014-11-01 14:00:19

回答

3

一個私有方法不能被覆蓋,只能解釋你在這裏看到的東西。你可以在你的main中調用這個方法,因爲main是在同一個類中,否則就不可能。

您正確地分析了將private更改爲protected時會發生什麼情況:該方法現在可以覆蓋,並且在調用子類實例時會執行該方法的「最近」定義。

+0

子類如何才能真正能夠從超類的私有部分運行代碼,這是否違反了封裝原則? – 2014-11-01 13:46:35

+0

以及如果私有方法會調用可覆蓋的方法呢?那麼會發生什麼? – 2014-11-01 13:47:42

+0

這不是發生了什麼,因爲你只能從同一個類的主要方法中做到這一點。你不能在其他地方做到這一點,所以沒有封裝問題 – Dici 2014-11-01 13:47:50

4

無法覆蓋私有方法。相反,子類是它隱藏它。這意味着當子類被多態使用時,該方法不被認爲是父類現有方法之一。這就像是一種不能通過多態性獲得的全新方法。

私有方法不是父類合同的一部分。多態性僅適用於父母合同一部分的方法。如果不是這樣,你可以通過改變作者希望它是私人的實施來讓一個班級採取與其合約不同的行動。如果作者希望你這樣做,他們會用protected代替。實際上,private方法就像final

在這個特定的主要方法中,因爲它是在實際的父類中定義的,所以它能夠看到一個私有方法並因此能夠調用它。如果你的主要方法已經在任何其他類中,並試圖調用它,它將失敗。