1

在泛型中查看此示例:

// abstract class   
public abstract class Shape {
    public abstract void draw(Canvas c);

}

//implementation of shape class
public class Rectangle extends Shape {
    private int x, y, width, height;
    public void draw(Canvas c) { ... }
}

//function to add rectangle object in a list
public void addRectangle(List<? extends Shape> shapes) {
    shapes.add(0, new Rectangle()); // compile-time error!
}

为什么这是编译错误?我无法弄清楚它是类型列表中的形状,它们是形状的子类,而矩形是形状的子类。

请帮我弄清楚这个查询。

4

2 回答 2

3

这是因为List< ? extends Shape >意味着传递的真实对象可能被声明为List<Rectangle>or List<Circle>

如果您尝试将 Rectangle 插入到 Circles 列表中,那将是一个真正的问题。

要使插入成功,您需要使用super,如List< ? super Shape >.

这意味着传递给这个函数的真实对象可能只声明为List<Shape>或什至List<Object>。这样的列表肯定可以同时包含 Rectangles 和 Circles (嘿,在后一种情况下,甚至 Apples 和 Oranges 也是如此)。

于 2012-06-16T11:29:16.997 回答
3

Java 教程中解释了这个确切的示例:

像往常一样,使用通配符的灵活性需要付出一定的代价。shapes 这个代价是现在在方法体中写入是非法的。例如,这是不允许的:

public void addRectangle(List<? extends Shape> shapes) {
    // Compile-time error!
    shapes.add(0, new Rectangle());
}

您应该能够弄清楚为什么不允许上面的代码。第二个参数的类型 shapes.add()? extends Shape- 的未知子类型Shape。由于我们不知道它是什么类型,所以我们不知道它是否是 Rectangle;的超类型。它可能是也可能不是这样的超类型,因此将 a 传递到那里是不安全的Rectangle

于 2012-06-16T11:29:29.007 回答