Chỉ cần để xây dựng trên câu trả lời @amit 's, đoạn mã không an toàn như là phương pháp Conc.execute
mất một BookStage
như một tham số và điều này sẽ được cố gắng để ép một Stage
thay cho rằng (và dĩ nhiên, không phải tất cả Stage
s là BookStage
s).
Tuy nhiên, hãy tưởng tượng chúng tôi muốn đi theo con đường khác, có nghĩa là, làm cho các kiểu tham số của BookePipeline.execute
một loại siêu của Stage
, chẳng hạn như Object
.
Vì vậy, chỉ cần làm rõ, chúng ta sẽ có:
interface Pipeline
{
void execute(Stage s);
}
interface BookPipeline extends Pipeline
{
@Override
void execute(Object s);
}
Và nơi Conc
cụ BookPipeline
:
Pipeline p = new Conc();
p.execute(new Stage());
này sẽ, về mặt lý thuyết, được an toàn vì Liskov năng thay thế đã không bị vi phạm - chúng tôi có thể chuyển an toàn Stage
vào bất kỳ triển khai nào có thông số Stage
trở lên. Điều này được gọi là contravariance. Java không hỗ trợ các loại đối số contravariant, tuy nhiên có languages.
Câu hỏi ban đầu của bạn liên quan đến covariant loại đối số không an toàn vì lý do được chỉ định (tuy nhiên, đủ lạ, một ngôn ngữ được gọi là Eiffel cho phép điều này).
Tuy nhiên, Java hỗ trợ biến thể trả lại loại. Hãy tưởng tượng Pipeline
đã có một
Stage getAStage();
nó sẽ là hoàn toàn hợp pháp cho BookPipeline
để ghi đè phương pháp này như sau:
@Override
BookStage getAStage();
Sau đó tưởng tượng chúng ta có:
public void someMethodSomewhere(Pipeline p)
{
Stage s = p.getAStage();
//do some dance on Stage
}
Giả sử chúng ta có một số lớp Donc
đã triển khai Pipeline
và vượt quá getAStage()
chính xác như được xác định trong Pipeline
(do đó vẫn trở Stage
), cả hai cuộc gọi là OK:
someMethodSomewhere(new Conc());
someMethodSomewhere(new Donc());
Bởi vì chúng ta luôn có thể đặt một bất cứ điều gì Stage
hoặc ít hơn (ví dụ BookStage
) trong một biến loại Stage
.
Vì vậy, để xây dựng lại và các quy tắc liên hệ đặc biệt với phương pháp trọng, một lớp mở rộng/giao diện đó sẽ ghi đè các phương pháp, chỉ có thể thực hiện các phương pháp đó tổng quát hơn trong những gì họ chấp nhận và cụ thể hơn trong những gì họ quay trở lại. (mặc dù trong trường hợp của Java, kiểu trả về chỉ cụ thể hơn được cho phép.)
Chỉ cần nhớ, PECS - Nhà sản xuất mở rộng, người tiêu dùng Siêu (Joshua Bloch, Effective Java)
được thông báo lỗi biên dịch là gì? Mã của bạn là gì? –