Nếu một kiểu thực hiện hai giao diện và mỗi giao diện interface
xác định một phương thức có chữ ký giống hệt nhau, thì thực tế chỉ có một phương thức và chúng không thể phân biệt được. Nếu, giả sử, hai phương thức có các kiểu trả về xung đột, thì đó sẽ là một lỗi biên dịch. Đây là quy tắc chung của thừa kế, ghi đè phương thức, ẩn và khai báo, và cũng áp dụng cho các xung đột có thể xảy ra không chỉ giữa 2 interface
phương thức được kế thừa , mà còn là interface
một class
phương thức và siêu phương pháp, hoặc thậm chí chỉ là xung đột do xóa kiểu tổng quát.
Ví dụ tương thích
Đây là một ví dụ trong đó bạn có interface Gift
một present()
phương thức (có, tặng quà) và interface Guest
cũng có một present()
phương thức (như trong, khách có mặt và không vắng mặt).
Presentable johnny
là cả a Gift
và a Guest
.
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { void present(); }
interface Presentable extends Gift, Guest { }
public static void main(String[] args) {
Presentable johnny = new Presentable() {
@Override public void present() {
System.out.println("Heeeereee's Johnny!!!");
}
};
johnny.present(); // "Heeeereee's Johnny!!!"
((Gift) johnny).present(); // "Heeeereee's Johnny!!!"
((Guest) johnny).present(); // "Heeeereee's Johnny!!!"
Gift johnnyAsGift = (Gift) johnny;
johnnyAsGift.present(); // "Heeeereee's Johnny!!!"
Guest johnnyAsGuest = (Guest) johnny;
johnnyAsGuest.present(); // "Heeeereee's Johnny!!!"
}
}
Đoạn trích trên biên dịch và chạy.
Lưu ý rằng chỉ có một @Override
điều cần thiết !!! . Điều này là do Gift.present()
và Guest.present()
là " @Override
tương đương" ( JLS 8.4.2 ).
Như vậy, johnny
chỉ có một thực hiện của present()
, và nó không quan trọng như thế nào bạn đối xử johnny
, cho dù là một Gift
hoặc là một Guest
, chỉ có một phương pháp để gọi.
Ví dụ không tương thích
Đây là một ví dụ trong đó hai phương thức được kế thừa KHÔNG @Override
tương đương nhau:
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { boolean present(); }
interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
// "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
// both define present(), but with unrelated return types"
}
Điều này tiếp tục nhắc lại rằng kế thừa các thành viên từ một interface
phải tuân theo quy tắc chung của tuyên bố thành viên. Ở đây chúng ta có Gift
và Guest
định nghĩa present()
với các kiểu trả về không tương thích: một void
kiểu khác boolean
. Vì lý do tương tự mà bạn không thể void present()
và một boolean present()
trong một loại, ví dụ này dẫn đến lỗi biên dịch.
Tóm lược
Bạn có thể kế thừa các phương thức @Override
tương đương, tuân theo các yêu cầu thông thường của phương thức ghi đè và ẩn. Vì họ LÀ @Override
-equivalent, hiệu quả chỉ có một phương pháp để thực hiện, và vì thế không có gì để phân biệt / chọn từ là.
Trình biên dịch không phải xác định phương thức nào dành cho giao diện nào, bởi vì một khi chúng được xác định là @Override
tương đương, chúng là cùng một phương thức.
Giải quyết sự không tương thích tiềm năng có thể là một nhiệm vụ khó khăn, nhưng đó lại là một vấn đề khác.
Người giới thiệu