Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a method a List<Interface> instead of List<Class>?

I have some objects that implement a common interface. Let's say I have Apple and some other Fruits that implement HasSeed and return their number of seeds.

I then have a service method, call it FruitProcessor here, with an addAll(List<HasSeed>) class. I thought I then can pass in a list of objects that implement the HasSeed interface, like a list of apples.

But I can't and the compiler complains that it's not applicable for the arguments. One more thing: I cannot change the List<Apple> to a List<HasSeed>. BUT I need a method in my FruitProcessor that can take any list of objects, and then calls getSeeds() no matter what object it is.

How could I adapt the following?

class Fruit {};
class Apple extends Fruit implements HasSeed {
   @Override
   int getSeeds() {
       return 5; //just an example
   }
}

class FruitProcessor {
    static void addAll(List<HasSeed> list) {
        for (HasSeed seed : list) {
            Sysout("the fruit added contained seeds: " + list.getSeeds());
        }
    }
}

class FruitStore {
    List<Apple> apples;
    FruitProcessor.addAll(apples); //The method addAll(List<HasSeed>) in the type FruitProcessor is not applicable for the arguments (List<Apple>)
}
like image 310
membersound Avatar asked Dec 04 '22 11:12

membersound


2 Answers

You have to use List<? extends HasSeed>

The reason behind is that List<Apple> doesn't extend List<HasSeed>. When you write List<? extends HasSeed> in your signature it means you accept any list of elements that implements the HasSeed interface. Which is why you can pass List<Apple> as a List<? extends HasSeed>

like image 119
phoenix7360 Avatar answered Mar 07 '23 08:03

phoenix7360


Use static void addAll(List<? extends HasSeed> list) since you declared your list as a List<Apple> and not List<HasSeed>.

like image 29
sp00m Avatar answered Mar 07 '23 08:03

sp00m