java方法不适用于参数(接口)

时间:2013-07-31 22:30:37

标签: java

我对java很新,并且没有多少使用接口,这是我想象的一个非常基本的问题。

我定义了一个接口,一个扩展它的第二个接口,然后是一个实现第二个接口的类:

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

然后我想调用一个方法,该方法将实现接口I1的对象集合作为参数:

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

但是当我尝试类似

时,我得到了上述错误
C2 aC2 = new C2();
List c2L = new List<I2>();
c2L.add(aC2);
C3.doI1Stuff(c2L);

作为一名java新手,我所做的对我来说似乎是合理的。为什么它不起作用,更有经验的程序员会做什么?我希望我在某个地方犯了很简单的错误,这实际上是可能的......

(修订后的问题:如果我正在处理单个C2对象,而不是它们的集合,它可以工作(作为回复说明)......)

1 个答案:

答案 0 :(得分:1)

<强>更新

哎呀,你的c2L是List,而不是List`。这应该编译 - 并且它确实如同其他评论的那样 - 尽管由于我在下面描述的相同原因它是危险的。我现在暂时留下这个答案,但如果发现它没用,我可以删除它


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

doI1Stuff期望List<I1>,但您传递List<I2>是不允许的。听起来很奇怪,“一袋苹果不是一袋水果”。原因是你可以将任何水果放入一袋水果中,例如香蕉,但你不能用Bag of Apple做到这一点。

要将它与您的示例相关联,请考虑还有class C1 extends I1doI1Stuff可以添加C3游侠,违反合同。它可能会澄清意识到您的参数名称错误,它应该是listOfImplementorsOfT1

解决问题的一种方法是将声明更改为

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

这表示该参数是{em>某些未知类型的列表extends I1List<I2>List<C2>List<C1>都满足约束条件。使用此声明,该方法无法向该列表添加任何内容,因为它不知道该类型是什么。