Odwołanie do generics java jest dobre (jdk site).
Rzeczywiście @Oli_Charlesworth dał dobrą odpowiedź, ale być może ta będzie bardziej kompletna.
W Collection<? extends Able>
nie można wstawić niczego, co jest poprawne.
Jeśli masz
class A implements Able {...}
i
class B implement Able {...}
Następnie Collection<? extends Able>
jest super typ zarówno:
Collection<A>
Collection<B>
Tak więc jest to legalne napisać oświadczenie jak
//Code snippet 01
Collection< ? extends Able > list;
Collection<A> listA;
Collection<B> listB;
list = listA;
list = listB;
Jest to rzeczywiście powód, dla którego istnieje symbol wieloznaczny Collection<? extends Able>
.
Ale tutaj rzeczy są coraz bardziej interesujące:
W Collection<A>
można wstawić tylko obiekty, które są A
(w tym podklasy). To samo dla Collection<B>
. W obu nie można dodać czegoś, co jest tylko Able
. Na przykład:
//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
Tak więc, jeśli grupa co widzieliśmy w code snippets 01 & 02
, można zrozumieć, że jest to absolutnie niemożliwe, aby kompilator zaakceptować oświadczenie jak:
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>
więc tak, super typ Collection< ? extends Able >
nie akceptuje dodawania niczego. Bardziej ogólne typy oferują przecięcie funkcjonalności podtypów i jako takie mniej funkcji podtypu. Tutaj tracimy możliwość dodawania obiektów A
i obiektów B
. Tych funkcji nastąpi później w hierarchii ... i to jeszcze nie oznacza, że możemy dodać coś w super klasie Collection< ? extends Able >
Dodatkowa uwaga:
Należy również pamiętać, że w Collection<Able>
można dodać cokolwiek chce tak:
Collection<Able> list;
list.add(new A()); //valid
list.add(new B()); //valid
Ale Collection<Able>
nie jest nadklasą Collection<A>
i Collection<B>
. Oznaczałoby to, podobnie jak w przypadku każdej relacji dziedziczenia, że podklasy mogą robić, co może zrobić ich nadklasa, ponieważ dziedziczenie jest specjalizacją. Oznacza to, że możemy dodać obiekty Object i B do obu podklas Collection<A>
i Collection<B>
, a tak nie jest. Tak, to nie jest nadklasą nie można mieć:
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
Zauważ, że dziedziczenie jest hyperonimic relacja (uogólnienie/specjalizacja) oraz zbiory zdefiniować meronimic relację (pojemnik/containee). I ból głowy polega na formalnym połączeniu obydwu form, mimo że jest on dość łatwo wykorzystywany przez niewyraźne istoty, na przykład we francuskiej wersji językowej: synecdocque. :)
co jest dokładnie taki błąd? – Bohemian