Вчера у меня было двухчасовое техническое телефонное интервью (которое я прошел, 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()
: at t1.equals(t3)
и t3.equals(t3)
. Последний случай достаточно очевиден, и в первом случае, хотя t1
имеет ссылку типа Object, он создается как тип Test, поэтому динамическое связывание должно вызывать переопределенную форму метода.
По-видимому, нет. Мой собеседник предложил мне запустить программу самостоятельно, и вот и вот, был только один выход из переопределенного метода: на линии t3.equals(t3)
.
Тогда мой вопрос, почему? Как я уже упоминал, хотя t1
является ссылкой типа Object (поэтому статическая привязка вызовет метод Object equals()
), динамическое связывание должно позаботиться о вызове самой конкретной версии метода на основе экземпляра типа Справка. Что мне не хватает?