membersound
membersound

Reputation: 86727

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

Upvotes: 10

Views: 3941

Answers (2)

phoenix7360
phoenix7360

Reputation: 2907

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>

Upvotes: 25

sp00m
sp00m

Reputation: 48817

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

Upvotes: 1

Related Questions