Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java method not applicable to the arguments (interfaces)

Tags:

java

I am fairly new to java and haven't used interfaces much, and this is what I imagine is a very basic question.

I define an interface, a second interface that extends it, and then a class which implements the second interface:

public interface I1 {
  public void doStuff();
}

public interface I2 extends I1 {
  public void doMoreStuff();
}

public class C2 implements I2 {
  public void doStuff(){
    // implements I1 as required
  }
  public void doMoreStuff(){
    // implements I1 as required
  }
}

I then want to invoke a method that has as an argument a collection of objects which implement the interface I1:

public class C3 {
   public static void doI1Stuff(List<I1> implementorsOfI1){
      // code here
   }
}

but I get the abovementioned error when I try something like

C2 aC2 = new C2();
List c2L = new List<I2>();
c2L.add(aC2);
C3.doI1Stuff(c2L);

What I've done seems reasonable to me as a java novice. Why doesn't it work, and what would a more experienced programmer do? I hope I've made very simple mistake somewhere and this is actually possible...

(revised question: it works (as replies stated) if I am dealing with a single C2 object, but not with a collection of them...)

like image 250
PGB Avatar asked Oct 20 '25 15:10

PGB


1 Answers

UPDATE

Ooops, your c2L is a List, not a List`. This should compile -- and it does for as it does for others who commented -- though it is dangerous for same reason I describe below. I will leave this answer here for now, but I can delete it if I find it is not useful


 public static void doI1Stuff(List<I1> implementorsOfI1)
 ...
 C3.doI1Stuff(c2L);

doI1Stuff expects a List<I1> but you are passing it a List<I2> which is not allowed. As strange as it sounds, "A bag of Apples is not a a bag of Fruit". The reason being that you can put any fruit in a Bag of Fruit, e.g. Banana but you can't do that with a Bag of Apple.

To relate it your example consider there is also a class C1 extends I1. doI1Stuff can add a C3 the paramer, breaking the contract. It might clarify to realize that your parameter is named wrong, it should be listOfImplementorsOfT1.

One way to fix your problem is to change the declaration to

 public static void doI1Stuff(List<? extends I1> implementorsOfI1)

This says the parameter is a list of some unknown type that extends I1. List<I2>, List<C2>, List<C1> all meet satisfy constraint. With this declaration, the method cannot add anything to that list, because it doesn't know what that type is.

like image 71
Miserable Variable Avatar answered Oct 23 '25 06:10

Miserable Variable



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!