Domanda
Sto avendo un momento difficile cercando di capire questo fuori. Dire che ho il seguente codice:
class Animal { }
class Mammal extends Animal { }
class Giraffe extends Mammal { }
...
public static List<? extends Mammal> getMammals() { return ...; }
...
public static void main(String[] args) {
List<Mammal> mammals = getMammals(); // compilation error
}
Perché il risultato incarico in un errore di compilazione? L'errore è qualcosa di simile:
Type mismatch: cannot convert from List<capture#4-of ? extends Mammal> to List<Mammal>
Secondo la mia comprensione della covarianza, il metodo restituisce un getMammals()
list
che sarà sempre contengono oggetti Mammal
quindi dovrebbe essere assegnabili. Che cosa mi manca?
Soluzione
A causa getMammals
potrebbe restituire un List<Giraffe>
, e se questo era convertibile a List<Mammal>
allora si sarebbe in grado di aggiungere un Zebra
ad esso. Non si può essere consentito di aggiungere un Zebra
a un elenco di Giraffe
, si può?
class Zebra extends Mammal { }
List<Giraffe> giraffes = new List<Giraffe>();
List<Mammal> mammals = giraffes; // not allowed
mammals.add(new Zebra()); // would add a Zebra to a list of Giraffes
Altri suggerimenti
Beh, non funziona così, purtroppo.
Quando si dichiara getMammals () per restituire List<? extends Mammal>
che significa che può tornare List<Mammal>
o List<Giraffe>
ma non List<Animal>
Il tuo main () dovrebbe assomigliare a questa:
public static void main(String[] args) {
List<? extends Mammal> mammals = getMammals();
Mammal mammal = mammals.get(0);
}
EDIT: Per quanto riguarda la covarianza, questo è ciò che di solito è intendesse dire:
class Animal {
public Animal getAnimal() {return this;}
}
class Mammal extends Animal {
public Mammal getAnimal() {return this;}
}
class Giraffe extends Mammal {
public Giraffe getAnimal() {return this;}
}
Come si può vedere permette di sovraccaricare tipo di ritorno di metodi quando si override del metodo.