2014-11-01 29 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

在这个特定的主要方法中,因为它是在实际的父类中定义的,所以它能够看到一个私有方法并因此能够调用它。如果你的主要方法已经在任何其他类中,并试图调用它,它将失败。