Polimorfismo - Não deveria se comportar como um animal?[Resolvido]

9 respostas
T

Galera, boa noite.
Desculpe se ja há uma pergunta igual a essa no forum, mas eu ja procurei e não achei.

É o seguinte:
Eu estou relendo o livro Use a cabeça - Java (so pra ver se tem duvidas e talz).

Fiz um teste que é mais ou menos assim:

Superclasse = Animal
Subclasse = cachorro

A classe animal tem um metodo chamado makeNoise(). Sobreescrevi esse metodo na subclasse.

Fiz uma outra classe qualquer que tem um metodo que recebe um animal como paramentro.
O metodo faz isso:

void veterinario(Animal a) {

a.makeNoise();

}

Minha duvida é a seguinte:

Eu passando um cachorro (ou gato,ou lagartixa,etc) para esse metodo (sendo essa classe uma subclasse de animal), dentro do metodo (void veterinario(Animal a)), ele não deveria se comportar como um animal e não como um cachorro? O metodo a ser chamado não deveria ser o metodo da classe declarada como parametro na assinatura do metodo?

Eu entendo que quando um metodo é sobreescrito, é chamada a versão mais especifica, mas não entendi isso com o parametro.

Obs: Eu fiz o teste e é chamado o metodo mais especifico. So queria tirar a duvida do Por que?

Valeu galera.
Espero ter sido o mais claro possivel.

9 Respostas

Eric_Yuzo

O parâmetro recebe um animal, que pode ser um cachorro, um gato, um elefante. Independente do animal que for passado, ele vai fazer barulho, porém cada animal tem uma forma diferente de fazer barulho. Seria muito estranho ter um cachorro que ao invés de latir, falasse ou miasse.

A questão de declarar o parâmetro do método como um animal, que seria abstrato, ao invés de cachorro ou papagaio, serve para não limitar este método, permitindo que se for criado uma nova classe que herde de animal, o método não precise ser modificado para poder recebê-lo. Mas quem executa o método makeNoise é o objeto que foi passado pelo parâmetro, que é a instância de um animal concreto.

T

Eric Yuzom value por responder.
Mas, tipo, como eu nao especifiquei o tipo de animal que eu vou passar, eu so limitei dizendo que seria um animal, o metodo makeNoise(), eu achei q seria chamado o metodo menos especifico nesse caso.

romarcio

Tem que ver como vc está fazendo a instância do objeto que passa por parâmetro.

Se for uma Instância do tipo “new Animal()” ele vai chamar o método original da classe Animal, mas se for uma instância do tipo “new Dog()” ele vai chamar o método da classe Dog.

Eric_Yuzo

O parâmetro que foi definido como Animal, nada mais é do que uma variável de referência, que vai aceitar qualquer coisa que seja um animal. Mas na memória não existe um animal instanciado literalmente, o que existe são cachorros, cavalos, porcos, etc. A herança faz com que todos os animais façam barulho, mas cada um tem sua própria forma de fazer isso.

Pense da seguinte maneira: A referência é de um Animal, mas o objeto é um Cachorro. Quem executa o método é o objeto e não a referência. A partir do momento que um método foi sobrescrito, é daquela forma que ele sempre será executado para toda instância daquele objeto.

T

E ai romarcio, blz?
Eu fiz os dois, passei new Animal() e new Dog().

Eu entendi como funciona. Eu so quero saber o Por que.

Sei q to sendo meio teimoso, mas quando eu li o livro pela primeira vez eu fiquei com a impressão de que ele se comportaria como um animal dentro do metodo (so podendo usar sua parte animal e nao sua parte dog, ou cate, ou seiLaMaisoQ,rsrs).

Entao eu achei que ele chamaria o metodo da referencia declarada na assinatura, e nao o da referencia passada.
Mas valeu pela ajuda, achei que ja me convenci.

Valeu.

romarcio

Sem problemas, pode perguntar a vontade.

Animal a = new Animal();

Animal a -> variável de referencia do tipo Animal;
new Animal() -> objeto do tipo Animal;

Quando se sobrescreve um método em uma classe herdada, o método chamado em uma instância utilizando polimorfismo, será sempre o do objeto e não da variável de referencia.

Exemplo de uso:

class Qualquer {
	public static void main(String[] args){
		Qualquer q = new Qualquer();
		
		//quando a1 passado por parametro, vai chamar o método da classe Animal
		//pq chama o método do objeto(new Animal()) e não da referencia(Animal).
		Animal a1 = new Animal();
		q.veterinario(a1);
		
		//quando a2 passado por parametro, vai chamar o método da classe Dog
		//pq chama o método do objeto(new Dog()) e não da referencia(Animal).
		Animal a2 = new Dog();
		q.veterinario(a2);

	}
	
        //O método recebe um variável de referencia do tipo Animal, mas vai depender de qual objeto ela foi criada para fazer a chamada
        // ao método makeNoise()
	void veterinario(Animal a) { 
		a.makeNoise(); 
	} 
}
T

Cara, valeu pela explicação.
E pensando bem, faz até mais sentido.
Se acontecesse como eu tinha pensado, uma boa parte das vantagens do polimorfismo não existiriam.

Valeu.
Assunto entendido.

Obs: 1º topico que eu abro no GUJ(sempre consegui acabar com minhas duvidas por outros que ja estavam abertos), e fui muito bem ajudado.
Parabens ao GUJ e aos participantes pela disposição de ajudar os outros.

romarcio

:slight_smile:

Legal que podemos tirar suas dúvidas.

Agora faz o seguinte, edita seu 1° post e no campo Titulo, coloca [Resolvido], assim: Polimorfismo - Não deveria se comportar como um animal?[Resolvido]

T

Feito.
Obrigado pela ajuda

Criado 7 de dezembro de 2010
Ultima resposta 7 de dez. de 2010
Respostas 9
Participantes 3