2017-04-19 101 views
0

我在圍繞這種Java繼承的奇怪行爲時感到困難。Java繼承私有和公共秩序

說,我有類私有方法方法1。然後有一個類孩子延伸類。 孩子也定義了方法方法1,但它是公開的。請看下面的例子:

public class Main { 
    public static void main(String[] args) { 

     Parent p = new Child(); 
     p.method2(); 
    } 
} 

class Parent{ 
    private void method1() { 
     System.out.println ("Parent's method1()"); 
    } 

    public void method2() { 
     System.out.println ("Parent's method2()"); 
     method1(); 
    } 
} 

class Child extends Parent { 
    public void method1() { 
     System.out.println ("Child's method1()"); 
    } 
} 

我不明白的是,輸出是低於!

Parent's method2() 
Parent's method1() 

我知道,因爲方法1家長方法1私人兒童無關與家長的。如果是這樣,那麼當方法2調用方法1,爲什麼家長方法1被稱爲不兒童的?特別是當實際類型是

好像完全沒有線索方法1方法2被調用。 我是否遺漏了繼承規則?請請幫助!

+0

我無法找到一個很好的鏈接,但你可以看看像[這裏](http://skeletoncoder.blogspot.com/ 2006/09/Java的教程 - 超載 - 是 - compile.html)。基本規則是Java在編譯時選擇重載(靜態綁定)並在運行時重載(動態綁定)。實際的JLS爲什麼你的示例是這樣的[right here](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.1)在頂部(在「如果表單是* MethodName *」下),但我不確定JLS在沒有背景的情況下是否有幫助。 – Radiodef

+0

這與'訂單'有什麼關係? – EJP

回答

2

private void method1()防止該方法被覆蓋。
因此,任何子類不能繼承此method1()
在你的代碼中,子類有它自己的獨立method1()


Parent p = new Child(); // We have p of Parent reference and is a Child object 
p.method2(); // At compile time this statement binds the method2() from Parent class 

因爲只有父類有method2(),它被調用。


但是,假設您已在您的Child類中重寫此方法。

class Child extends Parent { 
    public void method1() { 
     System.out.println("Child's method1()"); 
    } 
    public void method2() { 
     System.out.println("Child's method2()"); 
    } 
} 

在這種情況下,即使在編譯時,method2()被綁定到父類。
但是在運行時,調用了Child類中的method2()。這是運行時多態性。

因此呼叫p.method2()輸出會一直

Child's method2() 
Child's method1() 
+0

謝謝!你的例子說得很清楚。當問題出現時,即使我知道它不是重寫的情況,但我仍然期待類似「運行時多態性」的規則,因爲似乎沒有線索method1將從method2調用。我猜Java取自當前類的可見狀態。 – GrinNare

+1

如果您想更多地瞭解它,並且瞭解更多關於它的工作方式,可以簡單地在Eclipse中單擊方法名稱,並查看突出顯示的方法(編譯時多態性)。然後檢查會告訴你哪個方法被調用的輸出(運行時多態) –

1

private方法和字段不是是遺傳的。 protected是您正在考慮的訪問修飾符。在你的文章中,這些方法是不相關的(除了具有相同的名稱)。

protected void method1() { 
    System.out.println ("Parent's method1()"); 
} 
+0

是的,我知道父母和孩子的方法1是無關的。但是,java如何找出調用父級的方法1?對象的實際類型是子對象,而不是父對象。 – GrinNare

+1

由於'method2'在'Parent'中,因此'Parent'中的'method1'具有可見性。同樣,如果你使'method1'' protected',它會被'Child'中的方法覆蓋。 –

+0

我想知道的是,如果有一個規則,例如在重寫的情況下。如果方法被覆蓋,實際類型決定調用哪個方法。然而,如果一個方法被重載(比如在這種情況下......不要認爲這是超載,但無論如何...)可見性優先。我對嗎? – GrinNare