2015-04-27 7 views
6

Ho una domanda sull'applicazione del polimorfismo: supponiamo di avere una classe Bird e ho molte classi che la estendono (come Pigeon, Falcon e così via). Successivamente, ho una classe Cage. In questa classe, voglio fare una lista di uccelli che vivono in quella gabbia (solo un tipo di uccello può vivere in ogni gabbia).Inizializzazione dell'elenco di oggetti usando il polimorfismo

A causa di ciò, non so il tipo esteso della lista (A Pigeon? O forse un Eagle?), L'unica cosa che so è che sarà un Bird.

Se Pigeon extends Bird

Uso del polimorfismo posso dichiarare un uccello come: Bird tom = new Pigeon(); invece di Pigeon tom = new Pigeon();

Allora, perché non posso inizializzare una cosa del genere nel costruttore: [...]

private List<Bird> birdList; 

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

Se non riesci a farlo, è possibile raggiungere il mio obiettivo in un altro modo?

+0

risposta breve perché non sono dello stesso tipo. – xiaoyi

+4

leggi questa discussione http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p –

risposta

8

Quello che vorresti è usare un tipo generico per la tua Cage per catturare il tipo esatto di uccello che vive nella gabbia.Come questo:

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

} 

Si potrebbe quindi utilizzare la gabbia in questo modo:

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

È possibile aggiungere al vostro uccello Pidgeon arraylist e quindi verificare l'istanza di:

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

L'intero punto del polimorfismo è di tipo _non_ do controllando a runtime il modo in cui hai suggerito. Guarda la risposta di yvilbe per una soluzione molto migliore. – Seelenvirtuose

2

Dal momento che in ogni gabbia vivere un solo tipo di uccello, è possibile utilizzare i tipi generici di digitare la vostra classe Cage.

Ad esempio, Cage<T> definirà un elenco di uccelli in questo modo: List<T> birdList.

1

Non si può fare:

Elenco uccelli = new ArrayList();

in java. Il tipo generico a sinistra deve essere esattamente uguale (o non deve essere uguale, se le wild card sono in gioco -? Estende T o? Super T) al tipo generico a destra.

Se fosse possibile allora sarebbe impossibile aggiungere nuove Aquila alla lista Data dichiarato come elenco di Bird - che non avrebbe alcun senso

Che cosa si può fare è:

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

(tutta la famiglia di Bird 's, tra cui Pigeon' s)

o:

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

La ragione per cui non si può fare List<Bird> birdList = new ArrayList<Pidgeon>() è perché poi qualcuno potrebbe usare il riferimento birdList di scrivere qualsiasi Bird sottoclasse alla tua ArrayList<Pidgin>. Questo non deve essere consentito dal controllo del tipo, un elenco di Pidgin deve contenere solo istanze Pidgin.

Arne fornisce una soluzione utilizzando un parametro di tipo su Cage. Se questo non è ciò che vuoi fare puoi dichiarare birdList con un wildcard type.

Il vostro esempio sarà simile a questa:

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

Un tipo superiore jolly limitato come questo dice al compilatore birdList contiene un elenco di alcuni sconosciuti sottoclasse di Bird. Ciò ha l'effetto che non è possibile aggiungere alcun elemento all'elenco poiché non si è sicuri di aggiungere il sottotipo corretto e quando si leggerà dall'elenco si otterranno riferimenti di tipo Bird.

Problemi correlati