2011-09-27 20 views
28

Ho qualche classe che funziona con le interfacce:Come convertire un elenco di oggetti in un elenco di interfacce?

Qui è l'interfaccia:

public interface Orderable 
{ 
    int getOrder() 
    void setOrder() 
} 

Qui è la classe lavoratrice:

public class Worker 
{ 
    private List<Orderable> workingList; 

    public void setList(List<Orderable> value) {this.workingList=value;} 

    public void changePlaces(Orderable o1,Orderable o2) 
    { 
    // implementation that make o1.order=o2.order and vice versa 
    } 
} 

Ecco un oggetto che implementa l'interfaccia:

public class Cat implements Orderable 
{ 
    private int order; 

    public int getOrder() 
    { 
     return this.order; 
    } 

    public void setOrder(int value) 
    { 
     this.order=value; 
    } 

    public Cat(String name,int order) 
    { 
     this.name=name; 
     this.order=order; 
    } 
} 

Nella procedura principale creo un elenco di gatti. Io uso glazed lists per aggiornare dinamicamente i controlli quando l'elenco viene modificato e quando viene creato un modello di controllo con questo elenco.

L'obiettivo è trasferire questo elenco su un oggetto di lavoro, quindi è possibile aggiungere alcuni nuovi gatti all'elenco nella procedura principale e l'operatore lo saprà senza impostare nuovamente la proprietà dell'elenco (l'elenco è lo stesso oggetto in main proc e in worker). Ma quando chiamo worker.setList(cats) avvisa di aspettarsi un ordinabile, ma ottenere un gatto ... ma Cat implementa ordinabile. Come lo risolvo?

Ecco il codice principale:

void main() 
{ 
    EventList<Cat> cats=new BasicEventList<Cat>(); 

    for (int i=0;i<10;i++) 
    { 
     Cat cat=new Cat("Maroo"+i,i); 
     cats.add(cat); 
    } 

    Worker worker=new Worker(); 
    worker.setList(cats); // wrong! 
    // and other very useful code 
} 

risposta

32

è necessario modificare la classe Worker in modo che accetti List<? extends Orderable>

public class Worker 
{ 
    private List<? extends Orderable> workingList; 

    public void setList(List<? extends Orderable> value) {this.workingList=value;} 

    public void changePlaces(Orderable o1,Orderable o2) 
    { 
    // implementation that make o1.order=o2.order and vice verca 
    } 
} 
+0

Questo approccio ha funzionato meglio per me poiché devo solo cambiare la firma del metodo "Lavoratore", non la dichiarazione di un array, che non volevo toccare in tutti i miei file. IMO un approccio più fattibile rispetto alla risposta suggerita di Matt Ball – Makibo

7

Dovrebbe funzionare solo se si cambia la dichiarazione di cats:

List<? extends Orderable> cats = new BasicEventList<? extends Orderable>(); 

for (int i=0; i<10; i++) 
{ 
    cats.add(new Cat("Maroo"+i, i)); 
} 

Worker worker = new Worker(); 
worker.setList(cats); 

See:

1
void main() 
{ 
    EventList<Orderable> cats = new BasicEventList<Orderable>(); 

    for (int i=0;i<10;i++) 
    { 
     Cat cat=new Cat("Maroo"+i,i); 
     cats.add(cat); 
    } 

    Worker worker=new Worker(); 
    worker.setList(cats); // should be fine now! 
    // and other very usefull code 
} 

Per lo più, solo la costruzione di un elenco di Orderables subito , dal momento che il gatto si implema Ordinabili, dovresti essere in grado di aggiungere un gatto alla lista.

nota: questo sono io indovinare velocemente

4

Se davvero vuole una nuova collezione del tipo di interfaccia. Quando ad esempio non possiedi i metodi che stai chiamando.

//worker.setList(cats); 
worker.setList(new ArrayList<Orderable>(cats)); //create new collection of interface type based on the elements of the old one 
Problemi correlati