1

我真的不明白为什么下面的代码不起作用。我希望B.f被打印出来。

public class Main {
    public static void main(String[] args) {
        B b = new B();
        b.g();
    }
}

class A {
    void g() {
        f();    /* or this.f() */
    }
}

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

编译器抱怨:

Main.java:13: error: cannot find symbol
        f();    /* or this.f() */
        ^
  symbol:   method f()
  location: class A
1 error

据我了解,thisin的动态类型A.g始终为B. 因此,Java 的动态方法查找应该能够找到B.fthis.f执行它。

4

2 回答 2

3

Java 的动态调度只能看到当前类或其超类上定义的方法。由于 A 没有定义方法,它看不到 B 定义了它,因此您会收到错误。

但是,如果该方法是私有以外的任何访问,B 可以覆盖它,因此即使在通过“A”实例类型访问该方法时,对 B 实例上的方法的调用也将动态分派给 B 的实现。

于 2018-09-23T03:26:59.900 回答
1

这将不起作用,因为 A 类对方法 f() 没有任何想法。如果您不想f()在 A 中定义,您可以制作f()abstract 而不是您可以制作类A也抽象:

abstract class A {
    void g() {
        f();    /* or this.f() */
    }

    abstract void f();
}

class B extends A {
    void f() {
        System.out.println("B.f");
    }
}
于 2018-09-23T03:49:42.483 回答