Quantcast

P^i

Your Online Tech Magazine

Sat05252013

Last update12:17:26 PM

Back You are here: Home More Programming and Web Programming Polymorphism and Generics

Polymorphism and Generics



Generic collections give you the same benefits of type safety that you've always had with arrays, but there are some crucial differences that can bite you if you aren't prepared. Most of these have to do with polymorphism.

You've already seen that polymorphism applies to the "base" type of the collection:

List<Integer> myList = new ArrayList<Integer>();

In other words, we were able to assign an ArrayList to a List reference, because List is a supertype of ArrayList. Nothing special there—this polymorphic assignment works the way it always works in Java, regardless of the generic typing.

But what about this?

class Parent { }
class Child extends Parent { }
List<Parent> myList = new ArrayList<Child>();

Think about it for a minute.
Keep thinking...

No, it doesn't work. There's a very simple rule here—the type of the variable declaration must match the type you pass to the actual object type. If you declare List<Foo> foo then whatever you assign to the foo reference MUST be of the generic type <Foo>. Not a subtype of <Foo>. Not a supertype of <Foo>. Just <Foo>.

These are wrong:

List<Object> myList = new ArrayList<JButton>(); // NO!
List<Number> numbers = new ArrayList<Integer>(); // NO!
// remember that Integer is a subtype of Number

But these are fine:

List<JButton> myList = new ArrayList<JButton>(); // yes
List<Object> myList = new ArrayList<Object>(); // yes
List<Integer> myList = new ArrayList<Integer>(); // yes

So far so good. Just keep the generic type of the reference and the generic type of the object to which it refers identical. In other words, polymorphism applies here to only the "base" type. And by "base," we mean the type of the collection class itself—the class that can be customized with a type. In this code,

List<JButton> myList = new ArrayList<JButton>();

List and ArrayList are the base type and JButton is the generic type. So an ArrayList can be assigned to a List, but a collection of <JButton> cannot be assigned to a reference of <Object>, even though JButton is a subtype of Object.

The part that feels wrong for most developers is that this is NOT how it works with arrays, where you are allowed to do this,

import java.util.*;
class Parent { }
class Child extends Parent { }
public class TestPoly {
public static void main(String[] args) {
Parent[] myArray = new Child[3]; // yes
}
}

which means you're also allowed to do this

Object[] myArray = new JButton[3]; // yes

but not this:

List<Object> list = new ArrayList<JButton>(); // NO!

Why are the rules for typing of arrays different from the rules for generic typing? We'll get to that in a minute. For now, just burn it into your brain that polymorphism does not work the same way for generics as it does with arrays.








blog comments powered by Disqus