Метод, выбранный компилятором, зависит от объявленного типа, а не от типа среды выполнения.
Первая серия, которая объявляется как переменная A
, может вызывать только методы A (независимо от того, какой тип среды выполнения, экземпляр которого A
, получает только из Object
):
A a = new A();
a.f(bb); a.f(x);
Для второй серии компилятор связывает методы с наиболее конкретным параметром, соответствующим вызову, поскольку C
является A
, и поэтому компилятор может связать любые открытые методы из них здесь:
C c = new C();
c.f(bb); c.f(q); c.f(x);
Но в последнем фрагменте кода, который, вероятно, задается вопросом, a
ссылается на C
как объект времени выполнения, но на A
как на объявленный тип:
A a = new A();
// ...
a = c;
a.f(bb); a.f(q); a.f(x);
Таким образом, могут быть вызваны только методы, определенные в A
.