2017-04-19 96 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