Kemarin saya melakukan wawancara telepon teknis selama dua jam (yang saya lulus, woohoo!), Tetapi saya benar-benar meredam pertanyaan berikut tentang dynamic binding di Java. Dan ini sangat membingungkan karena saya dulu mengajarkan konsep ini kepada mahasiswa ketika saya masih menjadi TA beberapa tahun yang lalu, jadi kemungkinan bahwa saya memberi mereka informasi yang salah sedikit mengganggu ...
Inilah masalah yang saya berikan:
/* 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);
}
}
Saya menegaskan bahwa output seharusnya berupa dua pernyataan cetak terpisah dari dalam equals()
metode yang diganti : at t1.equals(t3)
dan t3.equals(t3)
. Kasus terakhir cukup jelas, dan dengan kasus sebelumnya, meskipun t1
memiliki referensi tipe Object, itu dibuat sebagai tipe Test, sehingga pengikatan dinamis harus memanggil bentuk metode yang diganti.
Sepertinya tidak. Pewawancara saya mendorong saya untuk menjalankan program sendiri, dan lihatlah, hanya ada satu keluaran dari metode yang diganti: di telepon t3.equals(t3)
.
Pertanyaan saya kemudian adalah, mengapa? Seperti yang sudah saya sebutkan, meskipun t1
merupakan referensi dari tipe Objek (jadi pengikatan statis akan memanggil equals()
metode Object ), pengikatan dinamis harus menjaga pemanggilan versi paling spesifik dari metode berdasarkan tipe referensi yang dipakai. Apa yang saya lewatkan?