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
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...
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 >

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
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 >
