Dúvida Generics - OCJP 6

6 respostas
diegofss11

Boa noite galera,

A minha dúvida é a seguinte.
Premissas:

class Automovel class Car extends Automovel class Golf Extends Car

<blockquote>class test{

List<? super Car> lista= new ArrayList();

lista.add(new Car());

lista.add(new Automovel()); // PORQUE EU N POSSO ADICIONAR AUTOMOVEL? AUTOMOVEL É SUPER EM COMPARAÇÃO A CAR. PELO QUE EU PERCEBI SÓ POSSO ADICIONAR SUBCLASSES.

lista.add(new Palio());

testMethod(lista)
void testMethod(List<? super Palio> listTest ){
     //aqui eu já posso receber a lista tranquilo por parametro, pois CAR é SUPER de Palio
 }

}

A questão é o seguinte, quando fui adicionar elementos na lista, parece que o <? super Car> está restringindo, só aceita subclasses de Car. Já quando vou passar por parâmetro, é considerando avalia a superclasses do mesmo.

Obrigado pela ajuda desde já !

6 Respostas

A

quem é super de car?? teoricamente somente a classe object. vc colocou super e não extends. O super é pra todos aqueles que estao acima (herançca ou polimorfismo ) de car. Por isso que ele não aceita. O car é super de car , pois como car é object tmb ele entende que é super ou do mesmo nível.

já este método está pedindo como parâmetros os super de palio , que deve ser palio já que vc não falou , então aceita tranquilo o palio e o proprio car.

diegofss11

Automovel é SUPER de car.

O super é pra todos aqueles que estao acima (herançca ou polimorfismo ) de car
. Concordo, todos acima de Car. Mas então porque eu posso adicionar Palio e Car na lista mesmo sendo subtypes ? E automovel que é o único SUPER de Car eu não posso ?

Já quanto ao método eu acho certo, aceitar somente super de CAR. O método sim faz sentido pra mim recebe lista de Car ou Automóveis, pois são SUPER. O que não faz sentido pra mim é poder adicionar somente subclasses (sendo que é super … deveria aceitar somente valores maiores na hierarquia)

Essa é minha dúvida.

A

ah é realmente não tinha notado que Veiculo era super de car .

Mas o problema de não aceitar o objeto veículo no método test ou mesmo um new Object() é que por padrão do java o compilador não sabe nada do que está ocorrendo no tempo de execução (teoricamente) e assim ele já preve possíveis erros em tempo de execução (ou pelo menos força vc nao cometer erros) .

Note que foi vc mesmo que declarou e inicializou a variavel de referência lista:

List<? super Car> lista= new ArrayList();

Como que ele vai aceitar automóvel se foi inicializado como Car?

Mesmo que vc tivesse feito isto , não funcionaria:

List<? super Car> lista= new ArrayList();
List<? super Car> lista= new ArrayList();

pq nao funcionaria?

Ora vc poderia resetar esta variável de referência da seguinte forma

lista= new ArrayList();

A tentativa de adicionar uma instancia Object () para o metodo teste irá dar problema. Já que o compilador nao sabe sobre o tipo de instanciação que será feita. O compilador sabe que passando uma instância Automóvel poderá ter prbolema no momento de execução se o tipo de inicialização que for feita não for automóvel ou um super tipo dele.

diegofss11

Mesmo inicializando assim:

List<? super Car> lista= new ArrayList(); eu só posso inserir subClasses de Car. Por qual motivo ? Quanto ao método teste eu entendi pois é possível associar dessa maneira

List<? super Car> lista= new ArrayList<QUALQUER CLASSE MAIOR OU IGUAL A CAR>();. Por isso eu posso recebe-la como argumento no método da maneira que eu estou esperando-a.

O problema que eu não entendi ainda é quanto a adição de elementos na List. Porque só aceita subClasses de Car sendo que estou declarando como List<? super Car> ?

A

Então vamos por outro exemplo digamos que carros implemente veiculos e quatro por quatro:

interface Veiculo {}
interface QuatroPorQuatro{}

public class Automovel{}

class car extends automoveis implements veiculos,QuatroPorQuatro {

}

Note que Carro é um automovel , Carro é um veiculo , Carro é um Quatro por quatro

Mas automóvel não é um Veiculo (pelo menos no nosso exemplo) e tmb não é um Quatro por quatro.

Agora vamos ao seu exemplo:

List<? super Car> lista= new ArrayList<Car>(); //ok 
List<? super Car> lista= new ArrayList<Automovel>(); //ok 
List<? super Car> lista= new ArrayList<Object>(); //ok 
List<? super Car> lista= new ArrayList<veiculo>(); //ok 
List<? super Car> lista= new ArrayList<QuatroPorQuatro>(); //ok

Se eu inicializar o Car com Interface quatro por quatro (devidamente implementada , claro) , ela é super de Car , mas não tem qualquer relação com Automovel .

como poderemos adicionar um Automovel se inicialzarmos dessa forma (QuatroPorQuatro)?

List<? super Car> lista= new ArrayList<QuatroPorQuatro>(); //ok lista.add(new Automovel())?

Automóvel não é um QuatroPorQuatro , e sim Car, Car é Automovel,QUatroporQUatro e veiculo.

Por isso que ele evita erro de tempo de execução, E da erro de Compilação (necessário cast) .

diegofss11

Agora entendi ! Valeu fera … muito obrigado pelo seu tempo !!! =)

Criado 6 de fevereiro de 2014
Ultima resposta 7 de fev. de 2014
Respostas 6
Participantes 2