Пояснение
Кстати A
вообще не имеет методов equals
.
Но вы делаете
ab.equals(a1)
ab.equals(b1)
И ab
- это:
A ab = new B();
Таким образом, хотя это на самом деле B
, переменная имеет тип A
.
Запустятся правила Javas для выбора методов в таких ситуациях. ищем метод equals
в классе A
. И на самом деле он есть, реализация по умолчанию унаследована от Object
. Он имеет подпись
public boolean equals(Object other)
, поэтому он решает эту подпись. Теперь он запрашивает фактический экземпляр за ab
, который имеет тип B
, для метода с этой сигнатурой. Он выбирает переопределенную реализацию в B
:
public boolean equals(Object other) {
System.out.print("Object");
}
и последовательно печатает Object
в обоих случаях.
Подробно
Подробно об этом определено в JLS§15.12. Выражения вызова метода . В нем говорится о поиске наиболее конкретного c соответствия . Правила могут стать довольно сложными, если вы углубитесь в них.
Некоторые выдержки:
Первый шаг в обработке вызова метода во время компиляции - выяснить имя метод, который нужно вызвать, и какой класс или интерфейс для поиска определений методов с таким именем.
На втором шаге выполняется поиск типа, определенного на предыдущем шаге, для методов-членов. На этом шаге используется имя метода и выражения аргумента для определения доступных и применимых методов, то есть объявлений, которые могут быть правильно вызваны для данных аргументов.
Может быть несколько таких методов , в этом случае выбирается наиболее конкретный c. Дескриптор (сигнатура плюс тип возврата) наиболее определенного c метода - это тот, который используется во время выполнения для выполнения отправки метода.
В классе или интерфейсе, определенных на этапе 1 времени компиляции (§15.12.1), ищутся все методы-члены, которые потенциально применимы к этому вызову метода; члены, унаследованные от суперклассов и суперинтерфейсов, включаются в этот поиск.
Если более одного метода-члена доступны и применимы для вызова метода, необходимо выбрать один, чтобы предоставить дескриптор для метода времени выполнения отправка. Язык программирования Java использует правило, согласно которому выбирается наиболее конкретный метод c.