Статический тип z
равен A
, поэтому z.f(-6)
может связываться только с методом в A
, который в данном случае равен A.f(int)
.
Язык разработан таким образом, чтобы
A z = new B(3.0);
z.f(-6);
всегда будет вести себя так же, как
A z = complicatedWayToComputeTrue() ? new B(3.0) : new A(3.0);
z.f(-6);
Если бы компилятор связывался с другой сигнатурой метода, потому что он может доказать, что A z
всегда содержит B
, то это привнесло бы в язык все виды нелокальных эффектов, затрудняя его отладку или поддержку Java-программы.
Представьте, что кто-то пытается поддерживать
final A z = complicatedWayToComputeTrue() ? new B(3.0) : new A(3.0);
// 1000 lines elided
z.f(-6);
, изменив его на
A z = new B(3.0);
// 1000 lines elided
z.f(-6);
Если компилятор теперь может доказать, что A
всегда является B
и связывает Z.f
с методом в B
, сопровождающий будет сбит с толку.