【问题标题】:Inherit in private methods of inner classes继承内部类的私有方法
【发布时间】:2012-09-14 14:11:51
【问题描述】:

让我们看下面的代码:

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();
    }
}

我希望该代码可以写成BA 改为写。

一个类可以调用它所包含的内部类的私有方法这一事实(至少对我来说)可能感觉很奇怪(为什么它们会这样?),但我真的不明白为什么多态性不起作用。

我的意思是,如果从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 时才会发生这种情况?

【问题讨论】:

    标签: java inheritance inner-classes private-methods


    【解决方案1】:

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

    相反,您有两个不相关的方法,它们恰好具有相同的名称。

    【讨论】:

      【解决方案2】:

      JLS #15.2.3中定义

      如果编译时声明有private修饰符,那么调用方式是非虚拟的

      还有JLS #15.4.4

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

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 2018-05-19
          • 2013-01-01
          • 2014-11-24
          • 1970-01-01
          • 1970-01-01
          • 2015-03-19
          • 2015-03-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多