Generics executar métodos do identificador

7 respostas
RichardVaugh

Pessoal, comecei a estudar generics e tenho uma dúvida.

Suponhamos que tenho uma interface AtributosCama:

public interface AtributosCama {
     boolean   isMacia();
}

e duas implementações dos AtributosCama:

public class CamaMacia implements AtributosCama {

     public boolean   isMacia(){
        return true;
     }
}

public class CamaDesconfortavel implements AtributosCama {

    public boolean   isMacia(){
        return false;
     }

}

Se eu quiser fazer algo do tipo:

public class Camas<T extends AtributosCama> {

    // como eu faço pra verificar dentro dessa classe os métodos de AtributosCama que eu qualifiquei após criar uma 
    //instancia do tipo Camas<CamaMacia> camas = new Cama<CamaMacia>();

}

Talvez eu esteja falando alguma idiotice, mas agradeço um esclarecimento ou sugestão de leitura.

[]'s

7 Respostas

E

Você precisa ter um atributo, ou parâmetro, ou variável do tipo T nessa classe.

Marky.Vasconcelos

Mas por que voce tem um Camas ?

Acho que voce queira fazer algo assim.

List<AttributosCama> list = new ArrayList<AttributosCama>();
list.add(new CamaMacia());
list.add(new CamaDesconfortavel());

for(AttributosCama cama:list)
System.out.println(cama.isMacia());

Repare que vai retornar true e false para o console.

RichardVaugh

Acontece que quando o usuário faz:

Camas<CamaMacia> camas = new Cama<CamaMacia>();

eu já gostaria de fazer dentro do contrutor algo pra executar o método que verifica se é ou não uma CamaMacia
o identificador que ele forneceu.

existe alguma forma de fazer algo como nessa idéia:

T.isMacia();

Alguma idéia ?

CrOnNoS

a resposta do enantiomero não serve ?

E

O construtor de Camas não tem acesso a um método estático do tipo T, apenas a métodos normais desse tipo T.

RichardVaugh

Será que existe algum workaround pra isso ?

Pois se eu faço

Camas<CamaMacia> camas = new Cama<CamaMacia>();

Em algum lugar deveria existir uma instancia do meu tipo T (AttributosCama) né ?

ViniGodoy

Não estou entendendo. Quando você fala de interface, você está falando de um atributo que os objetos da sua classe vão ter.

Esses são os objetos que vão dentro da lista, que serão do tipo designado entre < >:

public void List<AtributosCama> listaCamas = new ArrayList<AtributosCama>();
listaCamas.add(new CamaMacia()); //Esse objeto retorna isMacia true
listaCamas.add(new CamaDuraFeitoPedra()); //Esse objeto retorna isMacia false
Se você quer uma lista que só aceite objetos do tipo CamaMacia, crie-a para o tipo CamaMacia:
public void List<CamaMacia> listaCamas = new ArrayList<CamaMacia>();
listaCamas.add(new CamaMacia());
listaCamas.add(new CamaDuraFeitoPedra()); //Erro de compilação. É uma lista de camas macias!

Você também pode criar uma classe, que só aceite "Ts" de um determinado tipo:

public class ListaDeCamaMacia<T extends CamaMacia>
{
    //implementação aqui
}
//Erro, essa lista só aceita camas macias
ListaDeCamaMacia<CamaDuraFeitoPedra> lista = new ListaDeCamaMacia<CamaDuraFeitoPedra>();

Da mesma forma, você pode definir método que só aceitem listas, cujo tipo T derive de cama macia:

public void metodoSuperMacio(List<T extends CamaMacia> camasMacias) {
     //faz qualquer coisa
}
Ou mesmo, parâmetros cujo T seja pai de CamaMacia:
public void avaliarMacioGeral(List<T extends CamaMacia> lista, Avaliador<T super CamaMacia> avaliador) {
   //faz qualquer coisa
}

Talvez se você explicar um pouco mais do porque você quer saber, no momento da criação da lista, se uma cama é macia ou não, a gente possa te orientar numa maneira melhor de contornar seu problema.

Criado 2 de setembro de 2009
Ultima resposta 3 de set. de 2009
Respostas 7
Participantes 5