继承内部类的私有方法

时间:2012-09-14 14:11:51

标签: java inheritance inner-classes private-methods

我们来看下面的代码:

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 个答案:

答案 0 :(得分:5)

您期望的行为来自虚拟方法 私有方法永远不会是虚拟的。

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

答案 1 :(得分:3)

它在JLS #15.2.3

中定义
  

如果编译时声明具有private修饰符,则调用模式为非虚拟

JLS #15.4.4

  

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

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

答案 2 :(得分:0)

  

在Java中,默认情况下所有非静态方法都是“虚函数”。   两种特殊的非静态方法是非虚拟的:那些   标记为关键字final,无法覆盖,和私有   方法,不是遗传的

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