Nếu kiểu trả về phải là kiểu của lớp mà thực hiện giao diện, sau đó những gì bạn muốn được gọi là một F-bounded type:
public interface A<T extends A<T>>{ public T b(); }
public class C implements A<C>{
public C b() { ... }
}
public class D implements A<D>{
public D b() { ... }
}
Nói cách, A
được khai báo một tham số kiểu T
mà sẽ đảm nhận giá trị của từng loại bê tông thực hiện A
. Điều này thường được sử dụng để khai báo những thứ như clone()
hoặc copy()
các phương pháp được đánh máy tốt. Một ví dụ khác, nó được sử dụng bởi java.lang.Enum
để khai báo rằng phương thức compareTo(E)
được thừa kế của mỗi enum chỉ áp dụng cho các enums khác thuộc loại cụ thể đó.
Nếu bạn sử dụng mẫu này thường xuyên, bạn sẽ gặp phải các tình huống mà bạn cần this
là loại T
. Thoạt nhìn, có vẻ như rõ ràng là , nhưng bạn thực sự cần phải khai báo phương thức abstract T getThis()
mà người triển khai sẽ phải thực hiện một cách trivially là return this
.
[1] Khi người nhận xét đã chỉ ra, có thể làm điều gì đó lén lút như X implements A<Y>
nếu X
và Y
hợp tác đúng cách. Sự hiện diện của phương thức T getThis()
làm cho nó rõ ràng hơn khi X
đang phá vỡ ý định của tác giả của giao diện A
.
Nguồn
2010-03-10 01:18:49
+! - Rất đẹp. Tôi đã học được điều gì đó ở đây. Cảm ơn, Matt. – duffymo
off-topic: cú pháp như thế này là lý do tại sao tôi làm hết sức mình để tránh tạo ra API tổng quát càng nhiều càng tốt. – dimitarvp
Câu trả lời hay (và một ví dụ tuyệt vời về sức mạnh của generics), nhưng điều này không ngăn cản các lập trình viên làm C thực hiện A (xem câu trả lời thứ hai của tôi). –
Cam