Динамическое связывание Java и переопределение методов - PullRequest
88 голосов
/ 26 ноября 2008

Вчера у меня было двухчасовое техническое телефонное интервью (которое я пропустил, woohoo!), Но я полностью задал следующий вопрос относительно динамического связывания в Java. И это вдвойне озадачивает, потому что я преподавал эту концепцию студентам, когда я был ТА, несколько лет назад, поэтому перспектива, что я дал им дезинформацию, немного тревожит ...

Вот проблема, которую мне дали:

/* What is the output of the following program? */

public class Test {

  public boolean equals( Test other ) {
    System.out.println( "Inside of Test.equals" );
    return false;
  }

  public static void main( String [] args ) {
    Object t1 = new Test();
    Object t2 = new Test();
    Test t3 = new Test();
    Object o1 = new Object();

    int count = 0;
    System.out.println( count++ );// prints 0
    t1.equals( t2 ) ;
    System.out.println( count++ );// prints 1
    t1.equals( t3 );
    System.out.println( count++ );// prints 2
    t3.equals( o1 );
    System.out.println( count++ );// prints 3
    t3.equals(t3);
    System.out.println( count++ );// prints 4
    t3.equals(t2);
  }
}

Я утверждал, что выводом должны были быть два отдельных оператора печати из переопределенного метода equals(): в t1.equals(t3) и t3.equals(t3). Последний случай достаточно очевиден, и в первом случае, даже если t1 имеет ссылку на тип Object, он создается как тип Test, поэтому динамическое связывание должно вызывать переопределенную форму метода.

Видимо, нет. Мой интервьюер посоветовал мне запустить программу самостоятельно, и вот, из переопределенного метода был только один выход: в строке t3.equals(t3).

Тогда мой вопрос: почему? Как я уже упоминал, несмотря на то, что t1 является ссылкой типа Object (поэтому статическое связывание будет вызывать метод equals() объекта), динамическое связывание должно позаботиться о вызове наиболее конкретной версии метода, основанного на методе. на экземплярный тип ссылки. Чего мне не хватает?

Ответы [ 13 ]

0 голосов
/ 16 ноября 2010

Очень ясно, что здесь нет понятия переопределения. Это перегрузка метода. метод Object() класса Object принимает параметр ссылки типа Object, а метод equal() принимает параметр ссылки типа Test.

0 голосов
/ 27 ноября 2008

Ответ на вопрос "почему?" Вот как определяется язык Java.

Цитировать статью Википедии о ковариации и контравариантности :

Реализована ковариация типа возврата на языке программирования Java версия J2SE 5.0. Типы параметров имеют быть точно таким же (инвариантным) для переопределение метода, в противном случае метод перегружен параллелью определение вместо.

Другие языки разные.

0 голосов
/ 26 ноября 2008

См. Также этот вопрос SO, тесно связанный: Переопределение JIRA равно меткой метода

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...