The reference to java generics is good (jdk site).
Indeed @Oli_Charlesworth gave a good answer, but maybe this one will be more complete.
In a Collection<? extends Able>
you can't insert anything that's right.
If you have
class A implements Able {...}
and
class B implement Able {...}
Then, Collection<? extends Able>
is a super type of both :
Collection<A>
Collection<B>
Thus it is legal to write some statement like
//Code snippet 01
Collection< ? extends Able > list;
Collection<A> listA;
Collection<B> listB;
list = listA;
list = listB;
That is indeed the reason why the wildcard notation Collection<? extends Able>
exists.
But, here things are getting more interesting :
In a Collection<A>
you can only insert objects that are A
(including subclasses). Same for Collection<B>
. In both you can't add something that is just Able
. For instance :
//Code snippet 02
listA.add( new A() ); //valid at compile-time
listA.add( new B() ); //not valid at compile-time
listB.add( new B() ); //valid at compile-time
listB.add( new A() ); //not valid at compile-time
Thus, if you group what we saw in code snippets 01 & 02
, you will understand that it's absolutely impossible for the compiler to accept a statement like :
Collection< ? extends Able > list;
list.add( new A() ); //not allowed, will work only if list is List<A>
list.add( new B() ); //not allowed, will work only if list is List<B>
So yes, the super type Collection< ? extends Able >
doesn't accept to add anything. More general types offer the intersection of functionalities of subtypes, and, as such, less features that subtype. Here, we lose the ability to add A
objects and B
objects. Those feature will happen later in the hierarchy... and it even means that we can't add anything in the super class Collection< ? extends Able >
Additional remark :
Also, note that in a Collection<Able>
you can add whatever you want like this :
Collection< Able > list;
list.add( new A() ); //valid
list.add( new B() ); //valid
But, Collection<Able>
is not a superclass of Collection<A>
and Collection<B>
. It would mean, as with any inheritance relation, that subclasses can do whatever their superclass can do, as inheritance is specialization. So, this would mean that we could add A objects and B objects to both subclasses Collection<A>
and Collection<B>
and that is not the case. So as it's not a superclass you can't have :
Collection<Able> list;
Collection<A> listA;
Collection<B> listB;
list = listA; //not valid because there is no inheritance hierarchy
list = listB; //not valid because there is no inheritance hierarchy
Note that inheritance is a hyperonimic relation (generalization/specialization) and collections define a meronimic relation (container/containee). And it's a headache to combine both of them formally, even though it's somewhat used quite easily by the fuzzy creatures humans are, for instance in the french figure of speech : synecdocque. :)