2012-09-14 55 views
0

让我们以下面的代码:继承的内部类的私有方法

public class Test { 

    class A { 
     public A() {} 

     private void testMethod() { 
      System.out.println("A"); 
     } 
    } 

    class B extends A { 
     public B() { super(); } 

     private void testMethod() { 
      System.out.println("B"); 
     } 
    } 

    public Test() { } 

    public A get() { 
     return new B(); 
    } 

    public static void main(String[] args) { 
     new Test().get().testMethod(); 
    } 
} 

我预计写代码B。代替写入A

它可能会感到奇怪(至少对我来说)一个类可以调用它包含的内部类的私有方法(为什么他们这样做?),但我真正无法理解的是为什么多态不起作用。

我的意思是,如果从Test.main()我们可以打电话A.testMethod()很明显,我们也打电话B.testMethod()。 Java也可以确定一个对象的动态类型,为什么Java调用声明类型的方法而不是动态类型?这种行为可以被检查:

public static void main(String[] args) { 
    B b = new Test().new B(); 
    A a = b; 
    b.testMethod(); // writes B 
    a.testMethod(); // writes A 
} 

另外,为什么会发生这种情况,只有当Test.A.testMethod()private

回答

3

它在JLS #15.2.3

定义,如果在编译时声明了private修饰符,然后调用模式非虚

而且JLS #15.4.4

如果调用模式是非虚拟的,不允许覆盖。类T的方法m是要调用的方法。

哪里T是声明的类型,你的情况A,因为(在你的情况B)而不是在运行时的实际类型的对象。换句话说,私有方法没有多态性。

0

在Java中,所有非静态方法默认为“虚拟函数”。 两种特殊的非静态方法是非虚拟的:标有关键字final的 (不能被覆盖),和 私有方法,这些方法不是继承的

http://en.wikipedia.org/wiki/Virtual_function#Java

5

你期望的行为源于虚方法。
私有方法永远不是虚拟的。

相反,您有两个不相关的方法碰巧具有相同的名称。