2009-07-26 18 views
7

Tôi đang gặp khó khăn khi cố gắng tìm ra điều này. Giả sử tôi có mã sau:Java covariance

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 
} 

Tại sao kết quả gán trong lỗi biên dịch? Lỗi này là một cái gì đó như:

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

Theo sự hiểu biết của tôi về hiệp phương sai, phương pháp getMammals() trả về một list rằng sẽ luôn chứa Mammal đối tượng nên nó phải được chuyển nhượng. Tôi đang thiếu gì?

Trả lời

19

getMammals có thể trả về List<Giraffe> và nếu điều đó được chuyển đổi thành List<Mammal> thì bạn có thể thêm Zebra vào đó. Bạn không được phép thêm Zebra vào danh sách Giraffe, phải không?

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

Vâng, nó không hoạt động như thế thật không may.

Khi bạn khai báo getMammals() để trở về List<? extends Mammal> nó có nghĩa là nó có thể trở lại List<Mammal> hoặc List<Giraffe> nhưng không List<Animal>

Yours main() sẽ trông như thế này:

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

EDIT: Về hiệp phương sai, đó là điều thường có nghĩa là:

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

Như bạn có thể thấy nó cho phép quá tải retu rn loại phương pháp khi bạn ghi đè phương pháp.

+0

+ 1, nhưng bạn có thể giải thích "Danh sách hoặc Danh sách nhưng không phải Danh sách" có nghĩa là gì không ?! : p –

+0

Định dạng lại để loại bỏ 'Danh sách hoặc Danh sách nhưng không gây nhầm lẫn' :-) –

+0

Các generics đã được xử lý như html, đã thoát ra –