2015-04-27 19 views
6

Tôi có câu hỏi về việc áp dụng đa hình: Giả sử tôi có một lớp Bird và tôi có nhiều lớp mở rộng nó (như Pigeon, Falcon v.v.). Tiếp theo, tôi có một lớp học Cage. Trong lớp học này, tôi muốn lập danh sách các loài chim sống trong lồng đó (chỉ có một loại chim có thể sống trong mỗi lồng).Khởi tạo danh sách đối tượng sử dụng đa hình

Do đó, tôi không biết loại mở rộng của danh sách (A Pigeon? Hoặc có thể là Eagle?), Điều duy nhất tôi biết là nó sẽ là Bird.

Nếu Pigeon extends Bird

Sử dụng đa hình tôi có thể tuyên bố một con chim như: Bird tom = new Pigeon(); thay vì Pigeon tom = new Pigeon();

Vậy tại sao tôi không thể khởi tạo một cái gì đó như thế trong các nhà xây dựng: [...]

private List<Bird> birdList; 

    public Cage() { 
     this.birdList = new ArrayList<Pigeon>(); 
     /* Instead of birdList = new ArrayList<Bird>(); */ 
    } 

Nếu bạn không thể làm điều đó, tôi có thể đạt được mục tiêu của mình theo cách khác không?

+0

câu trả lời ngắn vì chúng không cùng loại. – xiaoyi

+4

đọc chủ đề này http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p –

Trả lời

8

Những gì bạn có thể muốn là sử dụng một loại chung cho Cage để nắm bắt chính xác loại chim sống trong lồng.Như thế này:

import java.util.ArrayList; 
import java.util.List; 

public class Cage<T extends Bird> { 

    private List<T> birdList; 

    public Cage() { 
     birdList = new ArrayList<T>(); 
    } 

    public void addBird(T bird) { 
     birdList.add(bird); 
    } 

} 

Bạn sẽ sau đó sử dụng lồng như thế này:

Cage<Eagle> eagleCage = new Cage<Eagle>(); 
eagleCage.addBird(new Eagle()); 
-1

Bạn có thể thêm vào Pidgeon chim ArrayList của bạn và sau đó kiểm tra trường hợp của:

private List<Bird> birdList; 

public Cage(){ 
    this.birdList = new ArrayList<>(); 
    birdList.add(new Pidgeon()); 

    //... 
    //Checking if it is a Pidgeon : 
    if(birdList.get(i) instanceof Pidgeon) { 

     //It is a pidgeon 

    } 
} 
+2

Toàn bộ các điểm đa hình là _not_ làm loại kiểm tra thời gian chạy theo cách bạn đề xuất. Nhìn vào câu trả lời của yvilbe cho một giải pháp tốt hơn nhiều. – Seelenvirtuose

2

Vì trong mỗi lồng sống chỉ có một loại chim, bạn có thể sử dụng các loại Generic gõ lớp Cage bạn.

Ví dụ: Cage<T> sẽ xác định danh sách chim theo cách này: List<T> birdList.

1

Bạn không thể làm:

Danh sách birds = new ArrayList();

bằng java. Kiểu chung ở bên trái phải bằng nhau (hoặc có thể không phải bằng nhau, nếu các thẻ hoang dã trong trò chơi - mở rộng T hoặc? Siêu T) thành loại chung chung ở bên phải.

Nếu nó đã có thể sau đó nó sẽ không thể để thêm Eagle mới vào danh sách khai báo là danh sách Bird - đó sẽ làm cho không có ý nghĩa

Những gì bạn có thể làm là:

List<Bird> birds = new ArrayList<Bird>(); 
birds.add(new Pigeon()); 

(tất cả các gia đình của Bird 's, trong đó có Pigeon' s)

hay:

List<? extends Bird> birds = new ArrayList<Pigeon>(); 
birds.add(new Pigeon()); // Adding is immpossible now - list can be read only now! 
4

Lý do bạn không thể làm List<Bird> birdList = new ArrayList<Pidgeon>() là bởi vì sau đó ai đó có thể sử dụng birdList tài liệu tham khảo để viết bất kỳ Bird lớp con để bạn ArrayList<Pidgin>. Điều này không được phép bởi trình kiểm tra loại, danh sách Pidgin chỉ được chứa Pidgin trường hợp.

Arne cho một giải pháp sử dụng một số loại trên Cage. Nếu đây không phải là điều bạn muốn làm, bạn có thể khai báo birdList với số wildcard type.

dụ của bạn sẽ trông như thế này:

class Bird {} 
class Pidgeon extends Bird {} 

class Cage { 
    // This is a wildcard type and can contain lists of any 
    // subtype to Bird, but you can't add elements to it. 
    private List<? extends Bird> birdList; 

    public Cage() { 
     this.birdList = new ArrayList<Pidgeon>(); 
    } 
} 

Một loại trên bị chặn wildcard như thế này cho trình biên dịch birdList chứa một danh sách các một số chưa biết lớp con để Bird. Điều này có tác dụng là bạn không thể thêm bất kỳ yếu tố nào vào danh sách vì bạn không thể chắc chắn thêm đúng loại phụ và khi bạn đọc từ danh sách, bạn sẽ nhận được tham chiếu loại Bird.

Các vấn đề liên quan