Java использует статическое связывание для перегруженных методов и динамическое связывание для переопределенных. В Вашем примере, равняется методу, перегружается (имеет различный тип параметрического усилителя, чем Object.equals ()), таким образом, названный метод связывается с ссылка тип во время компиляции.
Некоторое обсуждение здесь
то, что это, равняется методу, не действительно релевантно, кроме него частая ошибка перегрузить вместо переопределения его, о котором Вы уже знаете на основе своего ответа на проблему в интервью.
Редактирование: хорошее описание здесь также. Этот пример показывает подобную проблему, связанную с типом параметра вместо этого, но вызванную той же проблемой.
я верю, была ли привязка на самом деле динамичной, то любой случай, где вызывающая сторона и параметр были экземпляром Теста, приведет к называемому переопределенному методу. Так t3.equals (o1) был бы единственным случаем, который не распечатает.
equals
метод Test
не переопределяет equals
метод java.lang.Object
. Посмотрите на тип параметра! Test
класс перегружается equals
с методом, который принимает Test
.
, Если equals
метод предназначается для переопределения, он должен использовать @Override аннотацию. Это заставило бы ошибку компиляции указывать на эту частую ошибку.
Интересно достаточно, в коде Groovy (который мог быть скомпилирован в файл класса), все кроме одного из вызовов выполнят оператор печати. (Тот, сравнивающий Тест с Объектом ясно, не назовет Test.equals (Тест) функция.) Это вызвано тем, что отличный ДЕЙСТВИТЕЛЬНО делает абсолютно динамический контроль типов. Это особенно представляет интерес, потому что он не имеет никаких переменных, которые явно с динамическим контролем типов. Я читал в нескольких местах, что это считают вредным, поскольку программисты ожидают отличный делать вещь Java.
Java не поддерживает ковариантность в параметрах, только в ответ типы.
, Другими словами, в то время как Ваш тип возврата в методе переопределения может быть подтипом того, что это было в переопределенном, который не верен для параметров.
, Если Ваш параметр для равняется в Объекте, Объект, помещение равняния с чем-либо еще в подклассе будет перегруженным, не переопределенным методом. Следовательно, единственная ситуация, где тот метод назовут, состоит в том, когда статический тип параметра является Тестом, как в случае T3.
Удача с процессом собеседования! Я хотел бы быть интервьюируемым в компании, которая спрашивает эти типы вопросов вместо обычных вопросов об алгоритме/структурах данных, которые я преподаю моим студентам.
Я думаю, что ключ заключается в том равняние (), метод не соответствует стандарту: Это берет в другом Тестовом объекте, не, Объект возражает, и таким образом не переопределяет равняние () метод. Это означает фактическую только перегрузку его, чтобы сделать что-то специальное, когда это дало Тестовый объект при предоставлении ему Объектных вызовов объектов Object.equals (Возразите o). Смотря тот код через любой IDE должен показать два равенство () методам для Теста.
Метод перегружается вместо переопределенного. Равняется всегда берут Объект в качестве параметра.
btw, у Вас есть объект на этом в эффективном Java Bloch (что необходимо владеть).
См. также это ТАК Вопрос, тесно связанный: Переопределение JAVA равняется причуде метода
Ответ на вопрос, "почему?", это - то, как язык Java определяется.
Для заключения в кавычки статья Wikipedia о Ковариантности и Контравариантности :
ковариантность типа Возврата реализована в версии J2SE 5.0 языка программирования Java. Типы параметра должны быть точно тем же (инвариант) для переопределения метода, иначе метод перегружается с параллельным определением вместо этого.
Другие языки отличаются.