[Resolvido]Exercício sobre polimorfismo

Seguinte, tenho o seguinte exercício aqui:

Criar uma superclasse chamada animal e as 3 seguintes subclasses: cachorro, cavalo e preguica. Segue as classes com seus respectivos atributos e métodos.
Classe animal:

public class Animal {
	String nome;
	int idade;
	
	//Metodos
	public void emitirSom()
	{
		System.out.println("NHA NHA NHA!");
	}
}

Sub classe cachorro:

public class Cachorro extends Animal {
	//Metodos
	public void correr()
	{
		System.out.println("Cachorro correndo...");
	}
	
	public void emitirSom()
	{
		System.out.println("AU AU AU!");
	}
}

Sub classe cavalo:

public class Cavalo extends Animal {
	//Metodos
	public void correr()
	{
		System.out.println("Cavalo correndo...");
	}
	
	public void emitirSom()
	{
		System.out.println("IRRRIINN");
	}
}

Sub classe preguica:

public class Preguica extends Animal {
	//Metodos
	public void subirArvore()
	{
		System.out.println("Preguica subindo em arvores...");
	}
	
	public void emitirSom()
	{
		System.out.println("AAAAAAHHHHZZZZ");
	}
}

Agora tenho que implementar o solicitado nesse tópico:

4 - Crie uma classe Zoologico, com 10 jaulas (utilize um array) coloque em cada jaula um animal diferente, percorra cada jaula e emita o som e, se o tipo de animal possuir o comportamento, faça-o correr.

Não consigo visualizar como criar as jaulas…seria um array de que tipo?
Achei um link com a apostila, os exercícios estão lá o final…assim fica mais fácil entender…

private Animal[] jaulas = new Animal[10];

lembre-se , alem de criar a classe animal, vc pode verificar que existe um coisa comum a muitos animais, que é correr…

portanto é cabivel ver, que todos estes podem responder a uma mesma interface, a um mesmo contrato, que é o ato de correr… pense nisso, e vc precisara disso para concluir essa parte do exercicio

Mas ai vc nao está instânciando a classe Animal, ou seja, criando 10 objetos do tipo Animal?
Eu criei uma sub classe de zoologico chamada jaula…o exercício nao ta pedindo pra criar 10 jaulas??

Lavieri, veja ai no link o exercicio…o método correr não pode fazer parte da superclasse…

Não, ele esta criando um espaço onde cabem 10 animais, uma array serve para guardar animais, e o axericio pede para usar arrays…

[code]public class Zoologico {
private Animal[] jaulas = new Animal[10]; //aki são 10 jaulas ^^

public void setJaula(int jaulaNumero, Animal animal) {
     jaulas[jaulaNumero-1] = animal; //aqui vc esta guardando o animal dentro da jaulaNumero
     //arrays vão de 0 ate seu tamanho -1, por isso se vc referenciar as jaulas de 1 - 10, vc precisa...
     //retirar 1, para referenciar a array, pois esta vai de 0 ate 9
}

}[/code]

era + ou - isso que o exercicio pedia… agora vc tem que arrumar 1 forma de fazer os animais emitirem som, e correrem se for possivel

sim é pra criar 10 jaulas, na verdade vc não precisa criar um classe para jaulas, pois estas não tem funcionalidade no seu modelo, portanto vc pode usar uma array (como o exercicio pede) ou uma coleção, para identificar as jaulas…

eu não falei pro método correr fazer parte da super classe ^^ … falei que para a segunda parte do seu exercicio, de fazer correr se possivel, vc vai precisar de Interfaces, que são "contratos" em uma interface vc identifica o comportamente de um objeto, e quando vc assina uma interface, vc esta comunicando a todos, que vc compartilha daquele comportamento…

existem certos comportamentos que independem de Herença, por exemplo, imagina as seguintes decendencias

Pessoa
-> Musico … e que musico tenha a capacidade de "tocar uma musica" playMusic()

Eletronico
-> AparelhoDeSom … e que o aparelho de som, tb possa "tocar uma musica" playMusic()
-> Celular … e que o celular tb possa tocar musica…

agora digamos que em uma sala eu tenha diveras pessoas, entre elas existam músicos, existam aparelhos de som, celulares, entre outras coisas…
Como listar todos os meus objetos ? e se possivel tocar uma musica ??? playMusic() ??

a forma de fazer isso é definindo comportamento, ou seja interface

public interface PlayMusic { public void playMusic(); }

com isso eu estou falando que, todos que assinam PlayMusic, tem a capcidade de tocar musica, ou seja, impelmentam um método playMusic() …

portanto, como não posso fazer, um Musico, um Aparelho de som e um Celular, descender de um mesmo objeto com capacidade de tocar, eu faço cada um deles assinar a interface PlayMusic, desta forma ficaria assim…

[code]public class Musico extends Pessoa implements PlayMusic {
//… outras coisas que musico possa fazer

public void playMusic() { //<== este método é obrigatorio quando implemento PlayMusic
     System.out.println(getName() + " toca seu instrumento"); //supondo que Pessoa tenha um método getName()
}

}[/code]

public class AparelhoDeSom extends Eletronico implements PlayMusic { public void playMusic() { //<== este método é obrigatorio quando implemento PlayMusic System.out.println("toca a faixa 1 do CD"); } }

agora sabendo disso… e digamos que eu tenha uma sala com varios objetos e pessoas

Object[] sala = new Object[20]; sala[0] = new Musico(); sala[1] = new Cadeira(); sala[2] = new Bola(); sala[3] = new AparelhoDeSom(); sala[4] = new Celular(); sala[5] = new Advogado(); //... etc etc etc

depois de ter a sala completa eu posso verificar se cada um dos objetos da sala assinam PlayMusic, e se este for o caso, fazer o objeto tocar a musica

[code]for(Object obj : sala) { //leia esse linha como: “Para cada Object de sala, que eu estou chamando de ‘obj’ faça…”
if (obj instanceof PlayMusic) { //leia essa linha como: “Se ‘obj’ for um tocador de musica (PlayMusic) então…”
PlayMusic tocador = (PlayMusic)obj; //aqui, como sei que este objeto é um PlayMusic,
//eu posso convertelo com segurança para um playMusic, através de cast

   tocador.playMusic(); //e posso usar esse método, pois PlayMusic tem esse método conforme explicado mais acima

}
}[/code]

como comentei, Interface são contratos, e quem assina uma interface, se obriga a implementar cada um dos seus métodos, ou seja, a se comportar como a interface…
Para seu exercicio existem comportamento, que independe do tipo de animal, e são intricicos a uns e não podem vim por herança, comportamentos como Cantar, Correr, Pular não pertecem a todos os objetos, mais podem ser passados via interface…

se ficar duvidas avisa…

Boa explicação, agora entendi…só achei estranho da apostila não falar nada sobre a tal interface, nunca iria conseguir fazer sozinho…Tipo, to tentando fazer uma função pra listar os animais que foram colocados nas jaulas, quero mostrar qual animal foi colocado, tipo na jaula 1 foi colocado o cachorro…

	public void listarAnimais()
	{
		for(int i =0; i<jaula.length; i++)
		{
			System.out.println(jaula[i].O QUE VAI AQUI?);
		}
	}

public void listarAnimais() { for(int i =0; i<jaula.length; i++) { System.out.println(jaula[i].getClass().getSimpleName()); } }

Ou, melhor ainda:

public void listarAnimais() { for(Animal animal : jaula) { System.out.println(animal.getClass().getSimpleName()); } }

[quote=gRoOve]Boa explicação, agora entendi…só achei estranho da apostila não falar nada sobre a tal interface, nunca iria conseguir fazer sozinho…Tipo, to tentando fazer uma função pra listar os animais que foram colocados nas jaulas, quero mostrar qual animal foi colocado, tipo na jaula 1 foi colocado o cachorro…

public void listarAnimais() { for(int i =0; i<jaula.length; i++) { System.out.println(jaula[i].O QUE VAI AQUI?); } } [/quote]

uma form apara saber o que é

jaula[i].getClass().getSimpleName(); //isso retorna o nome simples da classe, sem conter o pacote...

Outra coisa é que vc pode tornar um objeto “imprimivel” sobrescrecendo o método toString()

Por exemplo, se vc implantar na sua classe animal como padrão

public class Animal { //... public String toString() { return getClass().getSimpleName(); } }

agora sempe que imprimir um animal diretamente, por padrão sairá o nome do tipo do animal, por exemplo, agora esse código vai imprimir o nome de cada bixo

public void listarAnimais() { for(int i =0; i<jaula.length; i++) { System.out.println(jaula[i]); } }

vc em uma subclasse pode reescrever o método, dando uma nova cara…

[code]public class Preguica extends Animal {
private String nome;

public Preguica() {
}

public Preguica(String nome) {
   this.nome = nome;
}

//..... outros métodos e campos


public String toString() {
   if (nome != null) //se existir um nome
      return super.toString() + //essa parte invoca o nome desta classe (como definido em Animal)
         ": " + nome; //aqui adcionam ": nome" do animal
   else
      return super.toString()
}

}[/code]

agora c vc fizer…

[code]Preguica fofura = new Preguica(“Fofura”);

system.out.println(fofura); //o resultado é =>> Preguica: Fofura[/code]

[quote=ViniGodoy] public void listarAnimais() { for(int i =0; i<jaula.length; i++) { System.out.println(jaula[i].getClass().getSimpleName()); } }

Ou, melhor ainda:

public void listarAnimais() { for(Animal animal : jaula) { System.out.println(animal.getClass().getSimpleName()); } }[/quote]

Nesses casos tem que sinalizar um objeto null, fora isso funcionou certino…outra coisa, o que exatamente quer dizer esse for?

for(Animal animal : jaula) {}

[quote=gRoOve]…outra coisa, o que exatamente quer dizer esse for?

for(Animal animal : jaula) {}

for = para

para cada Animal da jaula guarda em animal e repetir o que esta dentro do {}

Animal maiusculo = a classe… animal minusculo igual a veriavel

Quer dizer:

"Para cada animal na jaula".

Isso aqui:

public void listarAnimais() { for(Animal animal : jaula) { System.out.println(animal.getClass().getSimpleName()); } }

É exatamente igual a isso aqui:

public void listarAnimais() { for(int i = 0; i < jaula.size(); i++) { Animal animal = jaula[i]; System.out.println(animal.getClass().getSimpleName()); } }

Mas mais fácil de escrever e menos sujeito a erros.

No caso cria-se uma variável do tipo Animal apenas pra rodar o laço?

na verdade vc não precisa definir a variável alem do que ja esta na declaração do laço for

for(Animal animal : jaula) {}  

a variável esta sendo criar ali, no proprio laço, e ali mesmo ela morre, a cada passagem pelo laço…

Então, foi isso que eu disse…não está sendo criada a variável dentro do for?

“Criar” variável é um termo estranho. :?

A variável é declarada para ser utilizada somente naquele bloco de código que é o laço. Dentro do laço, esta variável será será atribuída um valor que valerá somente por uma iteração do laço, na próxima iteração será atribuído o próximo valor, e assim por diante até acabar. Quando ele sair do laço, o escopo dessa variável termina, e ela não será mais visível ou acessível, assim o objeto poderá ser recolhido e a memória liberada, caso possível.