我对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对象,而不是它们的集合,它可以工作(作为回复说明)......)
答案 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 I1
。 doI1Stuff
可以添加C3
游侠,违反合同。它可能会澄清意识到您的参数名称错误,它应该是listOfImplementorsOfT1
。
解决问题的一种方法是将声明更改为
public static void doI1Stuff(List<? extends I1> implementorsOfI1)
这表示该参数是{em>某些未知类型的列表extends I1
。 List<I2>
,List<C2>
,List<C1>
都满足约束条件。使用此声明,该方法无法向该列表添加任何内容,因为它不知道该类型是什么。