0

Possible Duplicate:
Most efficient way to cast List<SubClass> to List<BaseClass>
why polymorphism doesn't treat generic collections and plain arrays the same way?

If I have an abstract base class BaseClass and I write a function expecting Collection<BaseClass> as its argument, calls to that function with a Collection<SubClass> of a class SubClass extends BaseClass fail to compile.

In the base class:

public void addLots(Collection<BaseClass> collection) {
    for(BaseClass yourbase : collection) {
        us.add(yourbase) //what you say!!
    }
}

And in the subclass:

public void addMoreLots(Collection<SubClass> collection) {
    addLots(collection); //FAILS TO COMPILE
}

Now I think I can see why this is: Collection<SubClass> is NOT a subclass of Collection<BaseClass>. What is the correct method of making this call?

Community
  • 1
  • 1
Andrew Wyld
  • 7,133
  • 7
  • 54
  • 96
  • Thanks—I couldn't find it though, and I think this addresses a different question (more focused on "how do I do this", less focused on "why are arrays different than collections"). This presumable applies to any generic, for example `WeakReference`. – Andrew Wyld Sep 03 '12 at 17:07

5 Answers5

2

In a pinch, Collections.unmodifiableCollection(Collection<SubClass>) can return a Collection<BaseClass>. (It makes the collection unmodifiable, of course, but that's what makes it safe to treat a Collection<SubClass> as a Collection<BaseClass>.)

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
1

<? extends BaseClass> should replace <BaseClass>. The correct syntax for addLots is:

public void addLots(Collection<? extends BaseClass> collection) {
    for(BaseClass yourbase : collection) {
        us.add(yourbase) //what you say!!
    }
}
Andrew Wyld
  • 7,133
  • 7
  • 54
  • 96
1

Collections are checked only during the compilation time, not during the run time, so this is done in order to protect a collection taking in the wrong type of object in.

Try it this way...

public <T extends BaseClass> void addLots(Collection<T> collection){ }

OR

public void addLots(Collection<? extends BaseClass> collection) {}

Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75
1

You can use

public void addLots(Collection<? extends BaseClass> collection) {
}

instead of

public void addLots(Collection<BaseClass> collection) {
}

which denotes a Collection of types which extends the base class can be a parameter.

Bharat Sinha
  • 13,973
  • 6
  • 39
  • 63
0
public void addLots(Collection<? extends BaseClass> collection) {
}

but with this you cannot call add to collection (i.e. you cannot do collection.add()),
but in this

public void addLots(Collection<? super SubClass> collection) {
}

you can call add (i.e. you can do collection.add()).

Piotr Sobiegraj
  • 1,775
  • 16
  • 26
Kailash
  • 21
  • 5