2009-07-26 40 views
7

私はこれを把握しようとしています。次のコードがあるとします:Java共分散

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 
} 

割り当てがエラーになるのはなぜですか?エラーのようなものである:共分散の私の理解によると

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

getMammals()方法は、それが割り当て可能でなければなりませんので、必ずMammalオブジェクトが含まれますlistを返します。私は何が欠けていますか?

答えて

19

getMammalsのでList<Giraffe>を返すことができ、そしてそれはList<Mammal>に変換可能だった場合、あなたはそれにZebraを追加することができると思います。 GiraffeのリストにZebraを追加することはできません。

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

これは残念なことにそのようには機能しません。

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

EDIT:共分散に関しては、それはだ)、それはそれは(ユアーズメインList<Mammal>List<Giraffe>なくList<Animal>

を返すことができることを意味List<? extends Mammal>を返すために

あなたがgetMammalsを(宣言)のようになります。

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

ご覧のとおり、retuを過負荷にすることができますメソッドをオーバーライドすると、メソッドの型が返されます。

+0

+1、しかし、あなたは「リストまたはリストではないがリスト」が何を意味するのか説明できますか? :p –

+0

混乱している「List or List but not list」を取り除くために書式を変更しました:-) –

+0

ジェネリックはhtmlとして扱われました。エスケープ –