Допустим, у нас есть следующий код
class TestEqual{
public boolean equals(TestEqual other ) {
System.out.println( "In equals from TestEqual" ); return false;
}
public static void main( String [] args ) {
Object t1 = new TestEqual(), t2 = new TestEqual();
TestEqual t3 = new TestEqual();
Object o1 = new Object();
int count = 0;
System.out.println( count++ );// shows 0
t1.equals( t2 ) ;
System.out.println( count++ );// shows 1
t1.equals( t3 );
System.out.println( count++ );// shows 2
t3.equals( o1 );
System.out.println( count++ );// shows 3
t3.equals(t3);
System.out.println( count++ );// shows 4
t3.equals(t2);
}
}
По сути, в классе TestEqual (который, конечно же, расширяет Object) у нас есть метод, который перегружает метод equals из Object.
Кроме того, у нас есть несколько переменных: объект t1, t2, экземпляр TestEqual, TestEqual t3, экземпляр TestEqual, и объект o1, экземпляр экземпляра Object.
Если мы запустим программу, это будет вывод.
0
1
2
3
In equals from TestEqual
4
Этот пример кажется немного более сложным, чем обычный Car c = new Vehicle(); c.диск(); потому что экземпляр объекта, из которого мы вызываем метод, отличается от его типа, а также экземпляр метода отличается от его типа.
Я хотел бы проверить, правильно ли я понял, что происходит, когда мы вызываем каждый метод, шаг за шагом относительно связывания.
show 0
t1.equals(t2)
show 1
t1 рассматривается как объект TestEqual. Метод equals перегружен, поэтому привязка является статической, это означает, что мы передадим t2 как объект, поэтому он вызовет метод equals, унаследованный от суперкласса Object, поэтому он не будет отображать никакого текста.
show 1
t1.equals(t3)
show 2
Это кажется немного странным. Я ожидал показать «In equals from TestEqual», потому что t3 является объектом TestEqual, поэтому следует вызывать equals из t1. Мое объяснение здесь будет заключаться в том, что t1 является статическим и рассматривается как объект, поэтому вызывается метод equals, унаследованный от класса объекта, а параметр TestEqual t3 преобразуется в объект. Но не означает ли это, что предыдущее объяснение от t1.equals(t2) неверно?
show 2
t3.equals(o1);
show 3
t3 — это объект TestEqual, параметр o1 — это объект, поэтому вызывается метод equals, унаследованный от объекта, поэтому ничего не печатается.
show 3
t3.equals(t3)
show 4
t3 — это объект TestEqual, параметр — это объект TestEqual, поэтому будет вызван перегруженный метод из TestEqual, выводящий «In equals from TestEqual».
show 4
t3.equals(t2)
t3 — это объект TestEqual, параметр — Object из-за статической привязки (перегруженный метод), поэтому вызывается метод equal, унаследованный от Object, и ничего не печатается.