Просто уточнить ответ @amit «s, то фрагмент кода является небезопасным как метод Conc.execute
принимает BookStage
в качестве параметра, и это будет пытаться выжать Stage
вместо этого (и, конечно, не все Stage
s - BookStage
s).
Однако, представьте, что мы хотели пойти в другую сторону, то есть, сделать тип параметра из BookePipeline.execute
типа А супер из Stage
, таких как Object
.
Так просто уточнить, мы имеем:
interface Pipeline
{
void execute(Stage s);
}
interface BookPipeline extends Pipeline
{
@Override
void execute(Object s);
}
А где Conc
орудия BookPipeline
:
Pipeline p = new Conc();
p.execute(new Stage());
Это, в теории, быть безопасным, потому что Лисков подставляемость не была нарушена - мы может безопасно передать Stage
в любую реализацию, которая приняла параметр Stage
или больше. Это известно как контравариантность. Java не поддерживает contravariant типы аргументов, однако есть languages, которые делают.
Ваш первоначальный вопрос относится к ковариантны типов аргументов, который является небезопасным по причинам, указанным (однако ни странно, язык называется Eiffel позволяет).
Java все же поддерживает ковариант . Представьте Pipeline
был
Stage getAStage();
было бы вполне законно BookPipeline
переопределить этот метод, как так:
@Override
BookStage getAStage();
Тогда представьте, что мы имели:
public void someMethodSomewhere(Pipeline p)
{
Stage s = p.getAStage();
//do some dance on Stage
}
Предположим, что мы имели некоторый класс Donc
который реализовал Pipeline
и перегрузил getAStage()
точно так, как он определен в Pipeline
(так еще возвращаясь Stage
), оба из этих вызовов в порядке:
someMethodSomewhere(new Conc());
someMethodSomewhere(new Donc());
Потому что мы всегда можем поставить Stage
или что-нибудь меньше (например, BookStage
) в переменной типа Stage
.
Так перефразировать правило относиться конкретно к переопределению метода, выступающему класс/интерфейсу, который переопределяет методы, может сделать только те методы более общих в том, что они принимают и более конкретных в том, что они возвращаются. (хотя в случае Java, только более конкретные типы возвращаемых разрешены.)
Просто помните, Печ - Производитель Расширяет, Consumer Супер (Джошуа Блох, Эффективное Java)
Что сообщение об ошибке компилятора? Какой у вас код? –