В интервью мне был предоставлен следующий код:
public abstract class Base {
public int x = 1;
public Base() {
foo();
}
public abstract void foo();
}
public class Derived extends Base {
int x = 2;
@Override
public void foo() {
System.out.println("Derived: "+x);
}
}
class Main {
public static void main(String... args) {
Base base = new Derived();
base.foo();
}
}
Они спросили:
Что будет напечатано?
Если мы использовали С++, я думаю, что код должен давать ошибку компиляции, потому что, когда конструктор Derived
вызывается сначала, вызывается конструктор класса Base
. На данный момент метод foo
не существует.
Кроме того, я знаю, что сначала вызывается метод наследуемого класса, прежде чем все переменные создаются.
Однако в Java мы получаем:
Derived: 0 Derived: 2
Почему?
Я знаю, что как в С++ Java наследование всегда основано на виртуальных таблицах,
и конструктор класса Base
вызывается перед конструктором класса Derived
.