Java子类作为参数

时间:2014-05-15 08:43:02

标签: java subclass extends

Class A
Class B extends A

public static List<A> doSomething(List<A> items, A item) {
    // manipulate items
    return items;
}

List<B> items = new ArrayList<B>();
B item = new B();

items = doSomething(items, item);
  

错误:方法doSomething(List&lt; A&gt;,A)不适用于参数(List&lt; B&gt;,B)

项目已被接受,但项目未被接受。 为什么我不能这样做?

正确的方法是怎样的?

4 个答案:

答案 0 :(得分:8)

您必须使用List<? extends A>

答案 1 :(得分:4)

List<B>不会延伸List<A>。这有很好的理由;非正式地,请考虑List<A>的合同,您可以在其中放置A的实例”对List<B>无效。

您需要表明您愿意接受A子类型的列表。您可以使用List<? extends A>之类的通配符来完成此操作。但是,您的返回类型也会变为List<? extends A>而您不希望这样。您真正想要的是,如果您传入List<B>,则返回类型为List<B>

要在没有强制转换的情况下正确执行此操作,您需要绑定类型并指定它可以子类A。

public static <T extends A> List<T> doSomething(List<T> items, T item) {
    // manipulate items
    return items;
}

这应该有用。

答案 2 :(得分:1)

即使B是A的子类,List也不是List的子类。

您应该以这种方式更改方法:

public  static  List<? extends A>doSomething(List<? extends A> items, A item) {
    // manipulate items
    return items;
}

并通过转换返回值来调用它:

items = (List<B>) doSomething(items, item);

请注意,通过这种方式,您可以调用方法作为参数传递,也可以调用A的其他潜在子类的List,然后返回值将是该子类的List(即不是List),因此它是你有责任知道演员是否合法。

答案 3 :(得分:0)

我认为不接受任何物品和物品。如果你改变像是明智的

List<A> items = new ArrayList<A>();
B item = new B();

items = doSomething(items, item);

现在你将获得

  

错误:方法doSomething(List&lt; A&gt;,A)不适用于   参数(List&lt; A&gt;,B)