Hôm qua, tôi đã có một cuộc phỏng vấn kỹ thuật qua điện thoại kéo dài hai giờ (mà tôi đã vượt qua, thật tuyệt!), Nhưng tôi đã hoàn thành câu hỏi sau về liên kết động trong Java. Và thật là khó hiểu vì tôi đã từng dạy khái niệm này cho sinh viên chưa tốt nghiệp khi tôi là một kỹ sư cách đây vài năm, vì vậy viễn cảnh mà tôi cung cấp cho họ thông tin sai lệch là một chút đáng lo ngại ...
Đây là vấn đề tôi đã được đưa ra:
/* 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);
}
}
Tôi khẳng định rằng đầu ra phải là hai câu lệnh in riêng biệt từ bên trong equals()
phương thức được ghi đè : at t1.equals(t3)
và t3.equals(t3)
. Trường hợp sau là đủ rõ ràng, và với trường hợp trước, mặc dù t1
có tham chiếu kiểu Đối tượng, nó được khởi tạo dưới dạng Kiểm tra kiểu, vì vậy liên kết động nên gọi dạng ghi đè của phương thức.
Rõ ràng là không. Người phỏng vấn của tôi đã khuyến khích tôi tự chạy chương trình, và này, chỉ có một đầu ra duy nhất từ phương thức bị ghi đè: tại dòng t3.equals(t3)
.
Câu hỏi của tôi sau đó là, tại sao? Như tôi đã đề cập, mặc dù t1
là một tham chiếu của kiểu Đối tượng (vì vậy liên kết tĩnh sẽ gọi equals()
phương thức của Đối tượng ), liên kết động nên quan tâm đến việc gọi phiên bản cụ thể nhất của phương thức dựa trên kiểu khởi tạo của tham chiếu. Tôi đang thiếu gì?