Olá pessoal
Eu não consegui entender ainda o conceito do super!
o extends blz … List<? extends T> onde ? é qualquer coisa que estenda ou implemente T, dessa forma consigo utilizar a lista polimorficamente, com exceção que não posso inserir elementos, mas oq quer dizer o super?
O Generic (<T>) informa que os objetos guardados no seu List, serão da classe informada. ex.:
class MinhaClasse{
//...
public void inserir(){
// implements
}
//...
}
Classe que usará a lista:
class Outro{
List<MinhaClasse> lst = new ArrayList<MinhaClasse>();
lst.add(new MinhaClasse()); // adiciona novo objeto na lista
lst.get(0).inserir(); // invoka o método inserir para o 1º reg da lista.
}
Abraços.
Eu cheguei a conclusão que é tudo o contrario do extends, nunca fui atras, foi soh testes que fiz e conclusões que tirei. Exemplo:
vc tem a classe A que implementa Serializable, X que extende de A e C que extende de X.
Se vc tem uma List<? extends A> vc:
-
- não pode incluir nada, porque vc não sabe ateh onde vai o ?.
-
- vai recuperar no minimo um A, vc sabe que a lista eh de algo que extenda A, então o minimo que tem ali eh A.
-
- essa lista pode receber um ArrayList<A>, ArrayList<X> ou ArrayList<C>, pois A,X e C satisfazem o extends de A.
Se vc tem uma List<? super A> vc:
-
- pode incluir de tudo abaixo de A (inclusive), eu imagino como tudo que tem como super A.
-
- vc vai recuperar no minimo um Object, depois no código abaixo acho que fica melhor para visualizar por que.
-
- essa lista pode receber um ArrayList<Object>, ou um ArrayList<Serializable>, mas não pode receber um ArrayList<X> ou ArrayList<C>, pois se recebesse uma List<C> não poderia incluir um X que tem A como super, devem ser listas que deixem incluir tudo que tem A como super, então não estaria certo.
Em codigo, se vc tem esse método:
public void x(List<? super A> list) {
...
}
e eu fizer:
x(new ArrayList<Object>())
x(new ArrayList<Serializable>())
x(new ArrayList<X>())
para o ArrayList de Object e Serializable funciona, pois nessas listas eu consigo incluir A, X e C, mas para o X não funciona. Por esse motivo ele retorna sempre Object, porque pode ser qq lista de algo que eh super de A, e que suporte incluir de A para baixo. Se eu deixasse passar um ArrayList<X> não conseguiria incluir o A, o que não estaria de acordo com a lista que eh ? super A. Agora se dentro do metodo eu tiver:
public void x(List<? super A> list) {
list.add(new Object());
list.add(new X());
}
o add para o Object não funciona pois Object não tem A como super, e o add para X funciona, pois este tem.
então, é isso que eu imagino para o super, mas nunca precisei usar, ateh hj soh usei extends
ps: se vc ver um B perdido ai no meio eh porque eu tinha colocado antes classe B, mas ai ele deixa em negrito qdo posto entre <>, então o B virou X, e eu não sei se alterei em tudo.
eh, serve para aquilo que o Fabio falou, com a “vantagem” de por fazer algo do tipo:
List<? super A> l = new ArrayList<Object>();
mas soh deixar incluir objetos to tipo A. Agora o por que fazer isso ai ao inves de
List<A> l = new ArrayList<A>();
eu ateh queria saber, porque ainda nunca senti necessidade de usar…
Sem contar que evita os famosos “casts”:
List<String> list = new ArrayList<String>();
Dessa forma eu defino em tempo de compilação que só haverá Strings dentro do ArrayList. E para recuperar não preciso criar um cast, basta fazer:
String nome = list.get(0)
Ao invés de:
String nome = (String) list.get(0)
Obrigado povo!
eu consegui entender, mas realmente ficou meio no ar, uma situação onde o super seria necessário!
Mas valeu pela explicação!!!
[code]public class Pai {
public Pai() {
System.out.println("Construtor da classe pai");
}
public Pai(String nome) {
System.out.println("Pai da filha: " + nome);
}
public void brigar(String nome) {
System.out.println("Pai brigando com a filha: " + nome);
}
}[/code]
[code]public class Filha extends Pai {
private String nome;
public Filha() {
super("Joanna");
}
public static void main(String[] args) {
Filha filha = new Filha();
filha.brigar("Joanna");
}
public void brigar(String nome) {
super.brigar(nome);
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}[/code]