質問

the following code is part of an abstract class which is meant to be subclassed to manage a specific kind of Shape. (it's actualy a repository for a specific class but that's not relevant now)

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
}

How can I accept a Shape-subclass as argument in addShape suitable to add to the ArrayList?

役に立ちましたか?

解決

I would write code like this:

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);
}

他のヒント

you can use protected List<Shape> shapesOfSpecificType; as mentioned in a comment. you can add any objects of Shape type to this list for eg:

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

When you try to insert a Shape into a List < ? extends Shape> the compiler complains because it cannot know what kind of elements are actually in the list. Consider this:

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

Now when you try to insert a Square which extends Shape into shapes, you would insert a Square into a list of Triangles. That's why the compiler complains. You should just take a List< 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

Have a look at: http://www.angelikalanger.com/Articles/JavaPro/02.JavaGenericsWildcards/Wildcards.html

This page explains nicely what works and what does not with typed collections.

First, unrelated to the issue I suggest you write code in terms of collection interfaces, rather than concrete classes:

protected List<? extends Shape> shapesOfSpecificType;

Secondly, if you wish to add objects that extend Shape to the list you will want to define it as

protected List<? super Shape> shapesOfSpecificType;

So anything that is a Shape can go in the list.

But as others have pointed out: Why do you need a bounded list, why not just a List<Shape>?

Cheers,

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top