JasonK
JasonK

Reputation: 361

Illegal to have abstract class list in java constructor?

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

Answers (2)

Bhesh Gurung
Bhesh Gurung

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

Yogendra Singh
Yogendra Singh

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

Related Questions