Jeszcze inaczej, bo jakoś nie mogę tego w pełni zrozumieć. Mam książkę Java podstawy Horstmanna i parafrazując z niej przykład:
public class Container<E> {
E element;
public Container(E element) {
this.element = element;
}
public E getElement() {
return element;
}
public void setElement(E element) {
this.element = element;
}
}
class Animal{};
class Dog extends Animal{};
I teraz 2 warianty:
1.java<? extends Animal>
2.java<? super Dog>
1.W klasie Container za "< E>" podstawiam "<? extends Animal>" i otrzymuję:
public class Container<? extends Animal> {
<? extends Animal> element;
public Container(<? extends Animal> element) {
this.element = element;
}
public <? extends Animal> getElement() {
return element;
}
public void setElement(<? extends Animal> element) {
this.element = element;
}
}
Wywołania:
Animal a = container.getElement(); //mogę, bo typ zwracany getElement jest albo Animal albo potomek [public <? extends Animal> getElement() ]
c.setElement(a); // nie mogę, bo nie wiem czy animal czy potomek jest parametrem funkcji [public void setElement(<? extends Animal> element)]
//Ok. Te dwa sa zrozumiałe,ale teraz:
- W klasie Container za "< E>" podstawiam <? super Dog> i otrzymuję:
public class Container<? super Dog> {
<? super Dog> element;
public Container(<? super Dog> element) {
this.element = element;
}
public <? super Dog> getElement() {
return element;
}
public void setElement(<? super Dog> element) {
this.element = element;
}
}
Wywołania:
container.getElement(); <- nie mogę, tzn. mogę ale tylko jako przypisanie do object. Object o = <? super Dog> [public <? super Dog> getElement() ]
c.setElement(new Dog()) <- mogę, ale dlaczego nie c.setElement(new Animal())?