Giusto per elaborare la risposta s' @amit, il frammento di codice è pericoloso come il metodo Conc.execute
prende un BookStage
come parametro e questo sarebbe cercare di spremere un Stage
al posto di quella (e, naturalmente, non tutti Stage
s sono BookStage
s).
Tuttavia, immaginare abbiamo voluto andare nella direzione opposta, cioè, fanno il tipo di parametro del BookePipeline.execute
un super- tipo di Stage
, come ad esempio Object
.
Quindi, solo per chiarire, avremmo:
interface Pipeline
{
void execute(Stage s);
}
interface BookPipeline extends Pipeline
{
@Override
void execute(Object s);
}
E dove Conc
attrezzi BookPipeline
:
Pipeline p = new Conc();
p.execute(new Stage());
Questo sarebbe, in teoria, essere al sicuro perché Liskov sostituibilità non è stata violata - abbiamo potrebbe tranquillamente passare un Stage
in qualsiasi implementazione che abbia un parametro Stage
o superiore. Questo è noto come controvarianza. Java non supporta i tipi di argomenti controvarianti, tuttavia ci sono languages che fanno.
tua domanda iniziale si riferisce a covariante tipi di argomenti che è pericoloso per i motivi specificati (tuttavia stranamente, un linguaggio chiamato Eiffel permette questo).
Java supporta tuttavia covariant restituisce tipi. Immaginate Pipeline
aveva un
Stage getAStage();
sarebbe perfettamente legale per BookPipeline
per ignorare questo metodo in questo modo:
@Override
BookStage getAStage();
Poi immaginate che abbiamo avuto:
public void someMethodSomewhere(Pipeline p)
{
Stage s = p.getAStage();
//do some dance on Stage
}
Supponendo che abbiamo avuto qualche classe Donc
che ha implementato Pipeline
e ha annullato getAStage()
esattamente come è definito in Pipeline
(così ancora il ritorno Stage
), entrambi di queste chiamate sono OK:
someMethodSomewhere(new Conc());
someMethodSomewhere(new Donc());
perché possiamo sempre mettere un qualcosa di Stage
o meno (per esempio BookStage
) in una variabile di tipo Stage
.
Quindi, per riformulare la regola di mettere in relazione in particolare al metodo di primaria importanza, una classe/interfaccia che si estende che sostituisce i metodi, non può che rendere tali metodi più generali in quello che accettano e più specifiche in quello che ritornano. (anche se nel caso di Java, tipi restituiti solo più specifiche sono ammessi.)
Basta ricordare, PECS - Produttore Estende, Super consumatori (Joshua Bloch, Effective Java)
Qual è il messaggio di errore del compilatore? Qual è il tuo codice? –