Polymorphism in generics?

Hello All,

I have a method that returns a List of a specific type.I would like to refactor the method to return a List of an interface it implements. How can I do so? More specifically, if I have a class:

publicclass Circleimplements Shape{...

I have a method:

public List<Circle> getAllCircles(){..

I don't have access to getAllCircles(), is there a way to assign?:

List<Shape> foo = getAllCircles();

Thanks in advance,

Steven

[681 byte] By [GeekLove_JavaStylea] at [2007-10-2 20:09:00]
# 1

No. List<Circle> is NOT a subclass of List<Shape>. If this were allowed, then you could do:

foo.add(new Square());

and the class that implements getAllCircles() would be a bit screwed because it would suddenly find its list of circles contains a square...

dannyyatesa at 2007-7-13 22:49:29 > top of Java-index,Core,Core APIs...
# 2

What do you mean by "I don't have access to getAllCircles()"? If you don't have access to the method, you can't call it.

dannyyates is right: if you could simply assign lists like that, the following code would compile and then break at runtime:

List<Circle> circles = new ArrayList<Circle>();

List<Shape> shapes = circles; // here's the problem

shapes.add(new Square());

Circle circle = circles.get(0); // but here's where it breaks

[/core]

However, if you need to operate on the list as a List<Shape>, you can achieve the same behavior by copying the list:

[code]

List<Shape> shapes = new ArrayList<Shape>(circles);

Of course, now you have two different lists. But the "shapes" list can now contain squares.

Cheers!

tvynra at 2007-7-13 22:49:29 > top of Java-index,Core,Core APIs...
# 3

Thank you. That was what I was looking for. I wanted to run:

List<Shape> shapes = new ArrayList<Shape>(circles);

When i said "I don't have access to getAllCircles()," it was a typo. I meant I don't have access to the source code and therefore cannot refactor the original method.

What I wanted to do was merge a list of shapes.

Technically, I had a method that returns a list of Value objects that implement an interface (I used shapes as a fictitious example). I didn't want to expose the actual implementing classes, just a restricted interface (with far less methods) to increase the probability of someone using my API correctly.

Thanks for all of your help,

Steven

GeekLove_JavaStylea at 2007-7-13 22:49:29 > top of Java-index,Core,Core APIs...
# 4

No problem; glad to help. :)

It is important to note, of course, that recreating the list does require time, so you'll want to be mindful of that if performance is a concern. However, if both the original list and the new list are ArrayLists, it effectively amounts to two memory copies. I mention this, though, because if one or the other were a LinkedList, the performance would be linear over a fairly expensive operation (creating the linked chain of nodes).

Enjoy. ;)

tvynra at 2007-7-13 22:49:29 > top of Java-index,Core,Core APIs...