dúvida sobre Generics. Utilização do 'extends' e o 'super'

6 respostas
E

Olá !!!

Alguém poderia me ajudar ?

Por que quando utilizo ‘List<? super Pai>’ eu consigo adicionar ‘Filho’ e ‘Filha’ ao conjunto ?

import java.util.List;
import java.util.LinkedList;

class Pai{}
class Filho extends Pai{}
class Filha extends Pai{}

public class Main{                             
     public static void main(String agss[]){          
              
              List<? extends Pai> p1 = new LinkedList<Pai>();      //linha1
              p1.add(new Filho());
              p1.add(new Filha());
              
              List<? super Pai> p2 = new LinkedList<Pai>();            //linha2
                                        
              p2.add(new Filho());
              p2.add(new Filha());          
       } 
}

Qual é a diferença entre a linha1 e a linha2 ???

6 Respostas

P

Primeiro, este código não compila, pois você não pode adicionar nada na lista quando usa o extends.

public void teste(List<? extends Pai>){}// Este método so recebe listas que foram "tipadas" com a classe Pai ou subclasses da mesma
public void teste(List<? super Pai>){}// Este método so recebe listas que foram "tipadas" com a classe Pai ou superclasses da mesma

Espero que ajude,
Flw

S
Olá eusoufeioedai, o método add é perigoso, pois ele pode adicionar algum tipo impróprio na coleção. Quando você usa o coringa <?>, você está dizendo ao compilador que você vai usar qualquer tipo genérico do tipo do argumento declaro, e vai invocar apenas métodos para lerem dados, e não para escreverem(add) dados. É por isso que o seu código não compila, experimente usar outra função que não modifique o conjunto. Por exemplo:
import java.util.List;
import java.util.LinkedList;

class Pai{}
class Filho extends Pai{}
class Filha extends Pai{}

public class Main{                             
     public static void main(String agss[]){          
              
              List<? extends Pai> p1 = new LinkedList<Pai>();      //linha1
//              p1.add(new Filho());
//              p1.add(new Filha());
  		        p1.size();	            
              List<? super Pai> p2 = new LinkedList<Pai>();            //linha2
                                        
//              p2.add(new Filho());
//              p2.add(new Filha());          
		        p2.size();
       } 
}
Para add um objeto na coleção de uma forma segura, use a palavra super:
import java.util.List;
import java.util.LinkedList;

class Pai{}
class Filho extends Pai{}
class Filha extends Pai{}

public class Main{                             
     public static void main(String agss[]){          
              
              List<? extends Pai> p1 = new LinkedList<Pai>();      //linha1
//              p1.add(new Filho());
//              p1.add(new Filha());
  		        p1.size();	            
              List<? super Filho> p2 = new LinkedList<Pai>();            //linha2
                                        
                p2.add(new Filho());
//              p2.add(new Filha());          
		        p2.size();
       } 
}
<? super Filho>
... você estará pedindo ao compilador que aceite um tipo genérico que seja um Filho ou um supertipo de Filho.
<? extends Pai>
... você estará pedindo ao compilador que aceite o tipo Pai e qualquer subtipo de Pai, apenas para leitura.

Qualquer dúvida, poste ae!

Abraço!

E

acho que entendi

P

No livro da certificação, a autora explica isso. Você pode adicionar qualquer elemento abaixo na arvore de herança, o seu objeto é do tipo Pai, já o List recebe qualquer lista que for pai ou superclasse da mesma. Tenta faze isso:

List<? super Pai> p2 = new LinkedList<Filho>();

E veja o que acontece.
Flw

E

deixa eu ver se entendi:

List<? extends Pai> —>Toda declaração que for "? extends" roda sem problema, mas não pode adicionar itens ao conjunto, é isso né ?


De acordo com o código abaixo

class Avo{}

class Pai extends Avo{}

class Filho extends Pai{}

As declarações possíveis são:

---------------
          List&lt;? super Avo&gt; p2 = new LinkedList&lt;Avo&gt;();                                                   
          p2.add(new Avo());                                 
          p2.add(new Pai());                                 
          p2.add(new Filho());                      
       
        ------------- 
          List&lt;? super Pai&gt; p2 = new LinkedList&lt;Avo&gt;();                                                   
       //   p2.add(new Avo());    &lt;--------------Gera erro                             
          p2.add(new Pai());                                 
          p2.add(new Filho());

        ------------- 
          List&lt;? super Filho&gt; p2 = new LinkedList&lt;Avo&gt;();                                                   
       //   p2.add(new Avo());    &lt;--------------Gera erro                             
       //   p2.add(new Pai());     &lt;--------------Gera erro                                                            
          p2.add(new Filho());                                 



é mais ou menos isso ???
P

É isso mesmo.
:grin:

Criado 26 de março de 2008
Ultima resposta 26 de mar. de 2008
Respostas 6
Participantes 3