Динамическое связывание Java не удалось - PullRequest
0 голосов
/ 23 сентября 2018

Я не очень понимаю, почему следующий код не работает.Я ожидаю, что будет напечатано 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

Насколько я понимаю, динамический тип this в A.g всегдаB.В результате поиск динамического метода Java должен быть в состоянии найти B.f для this.f и затем выполнить его.

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018

Это не будет работать, так как класс A не имеет представления о методе f ().Если вы не хотите определять f() в A, вместо этого вы можете сделать f() абстрактным, для которого вы можете сделать класс A также абстрактным:

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

    abstract void f();
}

class B extends A {
    void f() {
        System.out.println("B.f");
    }
}
0 голосов
/ 23 сентября 2018

Динамическая диспетчеризация Java может видеть только методы, определенные в текущем классе или его суперклассах.Поскольку A не определяет метод, он не может видеть, что B определяет его, и вы получаете сообщение об ошибке.

Однако, если у метода есть любой доступ, отличный от private, B может переопределить его и, следовательно, вызвать метод в экземпляре.B будет динамически отправляться в реализацию B, даже когда доступ к методу осуществляется через тип экземпляра "A".

...