Dúvida sobre Generics e Herança

4 respostas Resolvido
genericherançajava
R

Olá pessoal,

Gostaria de esclarecer uma dúvida sobre a seguinte situação:
Tenha a seguinte hierarquia de classes no model:

public abstract class Mensagem {
}

public class Email extends Mensagem{
}

public class Sms extends Mensagem{
}

E a outra hierarquia de herança utilizando Generics:

public interface Emissor<T extends Mensagem> {
	public void enviar(List<T> lista);
}

public class EmissorDeEmail implements Emissor<Email> {
	@Override
	public void enviar(List<Email> lista) {
		// TODO Auto-generated method stub
	}
}

public class EmissorDeSms implements Emissor<Sms>{
	@Override
	public void enviar(List<Sms> lista) {
		// TODO Auto-generated method stub
	}
}

Eu imaginei que poderia utilizar essas classes da seguinte forma:

public static void main(String[] args) {
		List<Sms> lista = new ArrayList<Sms>();
		Emissor<Mensagem> emissor = new EmissorDeSms();
		emissor.enviar(lista);
	}

Mas o compilador indicar erro na hora de instanciar o emissor, com a seguinte mensagem:

Multiple markers at this line
	- Type mismatch: cannot convert from EmissorDeSms to 
	 Emissor<Mensagem>

Não sei se formulei os generics de forma errada. Por isso gostaria de ajuda para verificar se é possível fazer dessa forma e onde posso está errando neste código.

Desde já agradeço.

Att;

4 Respostas

M

Ele está gerando o erro devido a variavel emissor estar recebendo um tipo incompativel de valor. O emissorDeSms gera utiliza um generics diferente do tipo Emissor. O que você pode fazer é não passar o generics na variavel emissor ou utilizar o generics de Sms nessa variavel.

R

Fale Matheus, tudo bem?

A minha ideia seria criar um metodo que retornasse um Emissor de Mensagem e baseado no parâmetro passado ele retornava ou um Emissor de SMS ou um Emissor de Email. Vc saberia qual a melhor forma de modelar para que funcionasse dessa forma?

M
Solucao aceita

Romário,
Não sei se entendi bem o que você quer fazer e o motivo de você fazer desse jeito, mas eu faria dessa forma:

public <E extends Mensagem> Emissor<E> getEmissor(Class<E> c) {
	if (c.isInstance(Email.class)) {
		return (Emissor<E>) new EmissorDeEmail();
	}
	return (Emissor<E>) new EmissorDeSms();
}

public void run() {
	Emissor<Email> emissorEmail = getEmissor(Email.class);
	Emissor<Sms> emissorSms = getEmissor(Sms.class);
}
R

Matheus,

Agradeço pela resposta. A sua solução funcionou bem o que eu estava pensando. Era exatamente isso que eu estava precisando.

Sobre o motivo de eu está fazendo desse jeito, é que estou apenas voltando a estudar padrões de projeto e gostaria de saber a melhor maneira de implementar esse cenário. Minha ideia era criar uma factory para obter o emissor de forma genérica.

Não sei se essa seria a forma mais elegante de implementar essa solução.

Se você tiver uma solução mais elegante, agradeceria muito se você compartilhasse.

Att;

Criado 15 de janeiro de 2020
Ultima resposta 15 de jan. de 2020
Respostas 4
Participantes 2