下面的代码是一个抽象类的一部分,它被子类化以管理特定类型的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适合添加到数组列表的参数?
我会写这样的代码:
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);
}
您可以使用评论中提到的protected List<Shape> shapesOfSpecificType;
。您可以将Shape类型的任何对象添加到此列表中,例如:
Circle extends Shape {
//body
}
Square extends Shape {
//body
}
shapesOfSpecificType.add(new Circle());//valid
shapesOfSpecificType.add(new Square());//valid
当您尝试将Shape插入到列表中时<? extends Shape>编译器会报错,因为它无法知道列表中实际存在的元素类型。想想看:
List<Triangle> triangles = new List<Triangle>();
List<? extends Shape> shapes = triangles; // that actually works
现在,当你尝试插入一个扩展Shape的正方形时,你将插入一个正方形到三角形列表中。这就是编译器报错的原因。你应该列个单子形状>:
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
本页很好地解释了类型化集合的作用和不作用。
首先,与这个问题无关,我建议您根据集合接口编写代码,而不是具体的类:
protected List<? extends Shape> shapesOfSpecificType;
其次,如果您希望将扩展Shape
的对象添加到列表中,则需要将其定义为
protected List<? super Shape> shapesOfSpecificType;
所以任何是Shape
的都可以放到列表中
但是正如其他人指出的那样:为什么你需要一个有界列表,为什么不只是一个List<Shape>
?
欢呼,