Reputation: 361
I'm trying to figure out why the following doesn't seem to work in Java.
Here's the basic abstract class:
public abstract class Shape {
}
Lets say it has two concrete classes, Circle:
public class Circle extends Shape {
}
and Square, which has multiple constructors:
public class Square extends Shape {
public Square(Shape shape)
{
// nothing
}
public Square(List<Shape> shapes)
{
// nothing
}
}
Given this code:
Circle c = new Circle();
List<Circle> cList = new ArrayList<Circle>();
Square s = new Square(c);
Square s2 = new Square(cList);
the last line produces the error:
The constructor Square(List<Circle>) is undefined.
But I have the constructor in Square which takes the parameter List<Shape>
, and Circle is a Shape - the constructor that takes a single Shape is fine. So I don't understand why I'm getting this error. Thanks for your help.
Upvotes: 1
Views: 259
Reputation: 51030
But I have the constructor in Square which takes the parameter List, and Circle is a Shape - the constructor that takes a single Shape is fine.
That's because of the fact that generic types are invariant in Java. We know Circle
is-a Shape
but still List<Circle>
is-not-a List<Shape>
, so you cannot substitute List<Circle>
with List<Shape>
. To fill this gap you have to use bounded wildcards as pointed out by @Yogendra.
You can find an explanation here.
Upvotes: 0
Reputation: 34387
Define your constructor as :
public Square(List<? extends Shape> shapes)
{
// nothing
}
Which means it accepts all classes which extend Shape
.
Precautionary note: Be aware of the side effects as well which arise because of the same fact i.e. it accepts all classes which extend Shape
.
Upvotes: 5