La referencia a los genéricos de java es buena (jdk site).
De hecho @Oli_Charlesworth dio una buena respuesta, pero tal vez esta sea más completa.
En un Collection<? extends Able>
no puede insertar nada que sea correcto.
Si tiene
class A implements Able {...}
y
class B implement Able {...}
Entonces, Collection<? extends Able>
es un tipo súper de ambos:
Collection<A>
Collection<B>
Por lo tanto, es legal para escribir alguna declaración como
//Code snippet 01
Collection< ? extends Able > list;
Collection<A> listA;
Collection<B> listB;
list = listA;
list = listB;
Esa es de hecho la razón por la que existe la notación comodín Collection<? extends Able>
.
Pero, aquí las cosas son cada vez más interesante:
En un Collection<A>
puedes colocar sólo los objetos que se A
(incluyendo las subclases). Lo mismo para Collection<B>
. En ambos no puedes agregar algo que es solo Able
. Por ejemplo:
//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
Por lo tanto, si el grupo lo que vimos en code snippets 01 & 02
, comprenderán que es absolutamente imposible que el compilador para aceptar una declaración como:
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>
Así que sí, el tipo súper Collection< ? extends Able >
no acepta agregar nada. Los tipos más generales ofrecen la intersección de funcionalidades de subtipos y, como tal, menos características que subtipo. Aquí, perdemos la capacidad de agregar objetos A
y B
. Aquellos función ocurrirá más tarde en la jerarquía ... y aún significa que no podemos añadir nada en la superclase Collection< ? extends Able >
observación adicional:
Además, tenga en cuenta que en un Collection<Able>
se puede añadir lo que quieren de esta manera:
Collection<Able> list;
list.add(new A()); //valid
list.add(new B()); //valid
Pero, Collection<Able>
no es una superclase de Collection<A>
y Collection<B>
. Significaría, como con cualquier relación de herencia, que las subclases pueden hacer lo que sea que su superclase puede hacer, ya que la herencia es especialización. Entonces, esto significaría que podríamos agregar objetos A y B a ambas subclases Collection<A>
y Collection<B>
y ese no es el caso. Así que ya que no es una superclase no se puede tener:
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
Nota que la herencia es una relación hyperonimic (generalización/especialización) y las colecciones de definir una relación meronimic (contenedor/containee). Y es un dolor de cabeza combinarlos formalmente, aunque se usa con bastante facilidad por las criaturas borrosas que son los humanos, por ejemplo en la figura francesa del habla: synecdocque. :)
lo que es exactamente el error? – Bohemian