How to convert list of objects to list of interfaces?
Asked Answered
N

4

43

I have some class that works with interfaces:

Here is the interface:

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

Here is the worker class:

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

Here is an object that implements the interface:

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

In the main procedure I create a list of cats. I use glazed lists to dynamically update controls when the list is changed and when a control model is created with this list.

The goal is to transfer this list to a worker object, so I can add some new cat to the list in the main procedure, and the worker will know about it without setting its list property again (list is same object in main proc and in worker). But when I call worker.setList(cats) it alerts about expecting an Orderable, but getting a Cat... but Cat implements Orderable. How do I solve this?

Here is the main code:

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
}
Nagaland answered 27/9, 2011 at 16:33 Comment(0)
L
69

You need to change the Worker class so that it accepts 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  
   }
}
Louralourdes answered 27/9, 2011 at 16:41 Comment(1)
This approach worked best for me since I only has to change the "Worker" method signature, not the declaration of an array, which I didn't want to touch in all my files. IMO a more feasible approach than Matt Ball s suggested answerRowdyism
S
13

If you really would like a new collection of the interface type. When for instance you don't own the methods you are calling.

//worker.setList(cats); 
worker.setList( new ArrayList<Orderable>(cats)); //create new collection of interface type based on the elements of the old one
Steerageway answered 18/11, 2014 at 7:56 Comment(0)
B
7

It should work if you just change the declaration of 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:

Bade answered 27/9, 2011 at 16:38 Comment(0)
B
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
}

Mostly, just construct a list of Orderables right away, since cat implements Orderable, you should be able to add a cat to the list.

note: this is me quickly guessing

Bigoted answered 27/9, 2011 at 16:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.