【问题标题】:Dynamic dispatch and access level of a method [duplicate]方法的动态调度和访问级别[重复]
【发布时间】:2014-07-06 08:57:13
【问题描述】:

考虑以下类:

public class A {
    public void foo() {
        System.out.println("A.foo()");
    }

    public void bar() {
        System.out.println("A.bar()");
        foo();
    }
}

public class B extends A {
    public void foo() {
        System.out.println("B.foo()");
    }

    public static void main(String[]
    args) {
        A a = new B();
        a.bar();
    }
}

这段代码的输出是A.bar(),然后是B.foo()。我注意到,如果我将方法 foo() 的访问级别从 public 更改为 private,则输出为:A.bar(),然后是 A.foo()

为什么?

【问题讨论】:

  • 因为private 方法没有被继承。

标签: java oop inheritance dynamic-dispatch


【解决方案1】:

如果A.foo() 是私有的,那么它不能被子类覆盖——任何其他类基本上应该不知道私有成员的存在。您不能覆盖您无法“看到”的成员。

来自section 8.4.8.1 of the JLS

在类C 中声明或继承的实例方法mC,从C 覆盖另一个在类A 中声明的方法mA,如果全部以下是正确的:

  • ...

  • 下列情况之一为真:

    • mA 是公开的。
    • mA 受到保护。
    • mA 在与C 相同的包中声明为具有包访问权限,C 声明 mC 或 mAC 的直接超类的成员。
    • mA 被声明为具有包访问权限,并且 mC 覆盖了来自 C 的某个超类的 mA
    • mA 被声明为具有包访问权限,并且 mC 覆盖了来自 C 的方法 m'(m' 不同于 mC和 mA),这样 m' 会覆盖来自 C 的某个超类的 mA

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 2012-11-26
    相关资源
    最近更新 更多