方法参数适合添加到上限ArrayList

时间:2013-01-03 08:08:11

标签: java generics wildcard bounded-wildcard upperbound

以下代码是抽象类的一部分,该类旨在被子类化以管理特定类型的Shape。 (它实际上是特定类的存储库,但现在不相关)

protected ArrayList<? extends Shape> shapesOfSpecificType;

public addShape(Shape shape){
    getShapes; //make sure shapeOfSpecificType is instantiated and load stuff from db
    shapesOfSpecificType.add(shape); //gives an compile error
}

如何在addShape中接受Shape-subclass作为适合添加到ArrayList的参数?

4 个答案:

答案 0 :(得分:0)

首先,与此问题无关我建议您根据集合接口而不是具体类来编写代码:

protected List<? extends Shape> shapesOfSpecificType;

其次,如果您希望添加将Shape扩展到列表的对象,则需要将其定义为

protected List<? super Shape> shapesOfSpecificType;

所以Shape 的任何内容都可以放在列表中。

但正如其他人所指出的:为什么你需要一个有界的清单,为什么不只是一个List<Shape>

干杯,

答案 1 :(得分:0)

您可以使用评论中提到的protected List<Shape> shapesOfSpecificType;。 您可以将任何Shape类型的对象添加到此列表中,例如:

Circle extends Shape {
 //body
}
Square extends Shape {
 //body
}
shapesOfSpecificType.add(new Circle());//valid
shapesOfSpecificType.add(new Square());//valid

答案 2 :(得分:0)

当您尝试将Shape插入List&lt; ?扩展形状&gt;编译器抱怨,因为它无法知道列表中实际包含哪种元素。考虑一下:

List<Triangle> triangles = new List<Triangle>();
List<? extends Shape> shapes = triangles; // that actually works

现在,当您尝试插入将Shape扩展为形状的Square时,您可以将Square插入三角形列表中。这就是编译器抱怨的原因。你应该拿一个List&lt;形状&GT;:

List<Triangle> triangles = new List<Triangle>();
List<Shape> shapes = triangles; // does not work!

// but
List<Shape> shapes = new List<Shape>();
shapes.insert(new Triangle()); // works
shapes.insert(new Square()); // works as well

查看:http://www.angelikalanger.com/Articles/JavaPro/02.JavaGenericsWildcards/Wildcards.html

这个页面很好地解释了哪些有效,哪些不适用于类型集合。

答案 3 :(得分:0)

我会写这样的代码:

protected ArrayList<Shape> shapesOfSpecificType;

//Triangle can be added
public void addShape(Shape shape){
    shapesOfSpecificType.add(shape);
}

//List<Triangle> can be added
public void addShapes(List<? extends Shape> shapes){
     shapesOfSpecificType.addAll(shapes);
}