Problema com polimorfismo

9 respostas
T

Olá, pessoal. Eu estou estudando polimorfismo e não peguei muito bem ainda a lógica.
Olha só o que eu fiz, quero fazer os métodos únicos de Gato e Elefante rodar normal. Vou mostrar o que eu fiz para vocês entenderem.

Classe Animal:
public class Animal {

    void beber() {
        System.out.println("Estou bebendo");
    }
}
Classe gato:
class Gato extends Animal{
    
    @Override
    void beber(){
        System.out.println("Estou bebendo com minha lingua");
    }
    
    void comer(){
        System.out.println("Estou comendo ração");
    }
Classe elefante:
class Elefante extends Animal{
    
    @Override
    void beber(){
        System.out.println("Estou bebendo com minha tromba");
    }
    
    void comer(){
        System.out.println("Estou comendo mato");
    }
}
Classe CriaAnimal:
public class CriaAnimal {

    void mostraAnimal(Animal a) {
        if (a instanceof Animal) {
            Gato gato = (Gato) a;
            gato.beber();
            gato.comer();
        } 
        if (a instanceof Animal) {
            Elefante elefante = (Elefante) a;
            elefante.beber();
            elefante.comer();
        } 
    }

    public static void main(String[] args) {
        CriaAnimal ca = new CriaAnimal();
        Animal elefante = new Elefante();
        Animal gato = new Gato();
        
        ca.mostraAnimal(gato);
        ca.mostraAnimal(elefante);
    }
}
Esta aparecendo isso: [red]
Estou bebendo com minha lingua
Estou comendo ração
Exception in thread "main" java.lang.ClassCastException: Polimorfismo.Elefante cannot be cast to Polimorfismo.Gato
	at Polimorfismo.CriaAnimal.mostraAnimal(CriaAnimal.java:15)
	at Polimorfismo.CriaAnimal.main(CriaAnimal.java:28)
Java Result: 1
[/red]

Aguardo respostas.

9 Respostas

Henrique.tenorio

void mostraAnimal(Animal a) { if (a instanceof Animal) { Gato gato = (Gato) a; gato.beber(); gato.comer(); } if (a instanceof Animal) { Elefante elefante = (Elefante) a; elefante.beber(); elefante.comer(); }

O problema está nas instruções if, análise a pergunta para o primeiro if:
o objeto real que a variável de referencia “a” referencia é um objeto da classe Animal? sendo que o correto seria: o objeto real que a variável de referencia “a” referencia é um objeto da classe Gato?
deste modo a conversão Gato gato = (Gato) a; seria segura. O mesmo vale para o segundo if, sendo agora Elefante no lugar de Animal.

ViniGodoy

A graça está em fazer esse método efetivamente usando o polimorfismo:

void mostraAnimal(Animal a) { animal.beber(); animal.comer(); }

Sem casts, sem nada.

E note que vai funcionar corretamente.

Com o instanceof, você não estará usando polimorfismo.

T

Consegui arrumar.
A dica de Henrique.tenorio que ajudou em meu problema.
Eu fiz isso:

void mostraAnimal(Animal a) { if (a instanceof Gato) { Gato gato = (Gato) a; gato.beber(); gato.comer(); } if (a instanceof Elefante) { Elefante elefante = (Elefante) a; elefante.beber(); elefante.comer(); } }

Não sei se era isso que ele explicou a fazer, mas fiz e deu certo.
Obrigado a todos pela ajuda. Até a próxima.

ViniGodoy

Porém desse jeito você não está usando polimorfismo.

T

Mas do seu jeito eu não consegui usar os métodos específicos de cada classe…
Poderia explicar melhor?
valeu

nel

ViniGodoy:
A graça está em fazer esse método efetivamente usando o polimorfismo:

void mostraAnimal(Animal a) { animal.beber(); animal.comer(); }

Sem casts, sem nada.

E note que vai funcionar corretamente.

Com o instanceof, você não estará usando polimorfismo.

Vini, o problema é que na classe Animal não tem o método comer. tugh, o que o Vini está querendo dizer é que se você usa um instance of perde o sentido do Polimorfismo, para o seu caso. O objetivo é que você utilize o método sem se preocupar com quem o implementa, seja gato, cachorro. A única pergunta, classe Animal também não deveria possuir o método “comer” ?

Se sim, basta adiciona-lo e a dica do Vini vai funcionar perfeitamente.
E não é somente uma dica, mas sim, o correto a ser feito.

Henrique.tenorio

Realmente esta seria a maneira correta de se fazer.

Henrique.tenorio

Uma das utilidades do instanceof é quando você quer acessar um método mais especifico para aquele tipo de Animal e que não seja comum aos outros objetos por exemplo:
Gato, Cachorro, CachorroAdaptado, todos eles herdam de Animal porém, o CachorroAdaptado poderia tem um método comerAdaptado(), uma funcionalidade diferente dos demais objetos. Deste modo você poderia utiliza assim:

void mostraAnimal(Animal a) {    
        animal.beber(); 
        
        if( a instanceof CachorroAdaptado )
             animal.comerAdaptado();    
        else{
              animal.comer()
        }
}

É claro que isto depende da situação, mas é uma utilidade do instanceof.

T

Valeu a todos, entendi já. O que eu queria era apenas testar como chamar um método que apenas tivesse em Cachorro e Gato, o nome comer foi o primeiro que veio a minha cabeça.
Mas vendo pela lógica, todos animais comem (eu axo ne hAIuhaia). nesse caso, teria que estar na classe Animal também…
Mas era isso, obrigado pela atenção de todos.

Criado 22 de abril de 2012
Ultima resposta 22 de abr. de 2012
Respostas 9
Participantes 4