2009-07-26 8 views
7

Ich habe eine harte Zeit versucht, dies herauszufinden. Angenommen, ich habe folgenden Code:Java Kovarianz

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 
} 

Warum führt die Zuweisung zu einem Kompilierungsfehler? Der Fehler ist so etwas wie:

Type mismatch: cannot convert from List<capture#4-of ? extends Mammal> to List<Mammal> 

Nach meinem Verständnis der Kovarianz, die getMammals() Methode ein list zurückgibt, die immer Mammal Objekte enthalten, so dass es belegbar sein sollte. Was vermisse ich?

Antwort

19

Da getMammals könnten List<Giraffe> zurückkehren, und wenn das zu List<Mammal> konvertierbar ist dann würden Sie in der Lage sein, ein Zebra, um es hinzuzufügen. Sie können nicht eine Zebra zu einer Liste von Giraffe hinzufügen, können Sie?

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 
6

Nun, so funktioniert es leider nicht.

Wenn Sie getMammals() erklären List<? extends Mammal> zurückzukehren bedeutet es, es List<Mammal> oder List<Giraffe> zurückkehren können, aber nicht List<Animal>

Ihre main() sollte wie folgt aussehen:

public static void main(String[] args) { 
    List<? extends Mammal> mammals = getMammals(); 
    Mammal mammal = mammals.get(0); 
} 

EDIT: Kovarianz angeht, das ist was normalerweise damit gemeint ist:

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;} 
} 

Wie Sie sehen können, erlaubt es, retu zu überlasten rn Art der Methoden beim Überschreiben der Methode.

+0

+ 1, aber könnten Sie erklären, was "Liste oder Liste, aber nicht Liste" bedeutet ?! : p –

+0

Umformatiert, um die verwirrende 'Liste oder Liste, aber nicht Liste' zu entfernen :-) –

+0

Die Generika wurden als HTML behandelt, escaped –