Validar objeto passado por parametro

Estou usando as mesmas classes desse exercício http://www.guj.com.br/posts/list/120633.java
Não estou conseguindo fazer o solicitado aqui: 3 Implemente uma classe Veterinario que contenha um método examinar() cujo parâmetro de entrada é um Animal, quando o animal for examinado ele deve emitir um som, passe os 3 animais com parâmetro.
Tenho esta classe:

public class Veterinario{
	public void examinar(Animal animal){
		if(animal.equals("Cachorro "))
		{
			System.out.println("AIIIIIIIIIIII");	
		}
		else if(animal.equals("Cavalo"))
		{
			System.out.println("AAAAAAAARGGGGGGGGGGG");
		}
		
	}
}
public class Cachorro extends Animal {
	public void emitirSom()
	{
		System.out.println("AHUUUUUUUUUUUUUUUUUUUU");
	}
	public String toString()
	{
		return "Cachorro";
	}
}

Estou tendo dificuldade em identificar a qual subclasse pertence o objeto, quero colocar um som diferente para cada animal examinado.

No caso sua classe Animal tem quais métodos?

Vou supor que ela tem: “emitirSom();”

Se esse for um método abstrato (um unico metodo abstrato obriga a classe toda ser abstrata) será melhor , porque irá fazer que qualquer classe que seja subclasse de animal TENHA OBRIGATORIAMENTE que sobrescrever o método “emitirSom()”
Ta ok… Vamos dizer que voce tenha esse cenario certo?
Entao voce tem ai a sua classe Cachorro que é uma subclasse de Animal. Então ela é obrigada a sobrescrever “emitirSom()” e isso você fez… Ok.

O enunciado que você colocou ai pede para voce fazer um método “examinar()” dentro da classe Veteriario, certo?
Ok voce já fez o método… So que o seu jeito de testar está meio equivocado… Por que?
Voce está testando atraves do “equals()” sem ter sobrescrito o mesmo antes de usa-lo. O método equals originalmente so testa se uma referencia aponta pro mesmo objeto que a outra referencia… Nesse caso voce está testando:

        if (animal.equals("Cachorro")) { // aqui voce testa se um objeto Animal aponta pra
            // um objeto String. Logicamente não.
        }

Voce pode arrumar isso facilmente porque você sobrescreveu o método “toString()” na classe Cachorro. Então se voce escrever

        if (animal.toString().equals("Cachorro")) { // o equals da classe String é sobrescrito e ele compara o valor
            // literal de uma String com outra. E ele compara case sensitive. 
            // Existe também o metodo equalsIgnoreCase() que compara ignorando caixa alta/baixa
            animal.emitirSom(); // voce ja escreve o som que o cachorro faz quando voce
        // escreveu a classe cachorro, entao so chame o metodo.
        }

Se de fato feito esse teste uma String for igual a outra String (lembre-se, compara valor literal então “Cachorro” é igual a “Cachorro” mas não é igual a “cachorro”, case sensitive!), o teste retorna true e executa o codigo do if.

Existem outras maneiras de fazer isso… So falei essa para seguir seu raciocinio!

Boa sorte!

O método examinar não deve ter nenhum print, mas deve chamar o método emitirSom.

public void examinar(Animal animal){  
    animal.emitirSom();
}

Se vc quer saber para qual subclasse sua superclasse aponta vc deverá utilizar o

instanceof
8)

pmlm matou, exatamente isso velho, vlw =D

O que seria esse método abstrato?

Editado

up!

Não upe tópicos!

Método abstrato é um método que não possui corpo, só definição. Por exemplo, você sabe que todo animal faz um som, certo? Nesse caso, a classe Animal pode conter um método assim:

public abstract class Animal { public abstract void emitirSom(); }

Então você faz a classe Cachorro:

public class Cachorro extends Animal { public void emitirSom() { System.out.println("AHUUUUUUUUUUUUUUUUU"); } public void toString() { return "Cachorro"; } }

E a classe cavalo:

[code]public class Cavalo extends Animal {
public void emitirSom() {
System.out.println(“AAAAAAAAAAAAAAAAARGGGGGGGGGGGGGG”);
}

public void toString() {
return “Cavalo”;
}
}[/code]

Então, como todo animal emite som (embora cada um a seu modo) e sua classe veterinário trabalha com animais, seu método emitirSom:

public class Veterinario{ public void examinar(Animal animal){ animal.emitirSom(); }

O java vai saber exatamente qual é o tipo de animal passado para a variável animal, e vai emitir o som certo. Esse método tem a grande vantagem de eliminar o if, o que facilita muito na hora de criar novos animais pro seu programa.

Para utilizar um método abstrato tenho que definir a classe que ele pertence como abstrata tb né? Caso tenha dentro da classe abstrata um método não abstrato, o que vai acontecer?

Não há problema algum… Classes abstratas podem conter metodos abstratos ou concretos.
Vamos dizer que você pense aí em alguma coisa que todos animais fazem de um jeito só (não pensei em nenhum, mas tenta pensar que exista =P)…
Então você pode escrever um método concreto na classe abstrata Animal, que todos que herdarem Animal farão a mesma “coisa”.

Na verdade para ter certeza que nenhum animal vai inventar um novo jeito de fazer essa tal “coisa” você terá de marcar o método como “final” também!

no seu exemplo:

[code]public abstract class Animal {

public void emitirSom(); // método abstrato, qualquer classe que herdar animal terá de implementalo.

public final void coisaQueTodoAnimalFaz() {

// alguma coisa que todo animal faz e sendo “final” ninguem poderá sobrescrever este método.
// método concreto, estas chaves mostram que o método ja foi implementado!
}
}
[/code]

Espero ter ajudado!

Na verdade, você pode até mesmo ter uma classe abstrata sem nenhum método abstrato!

Saquei, mas qual a diferença entre uma classe ser abstrata ou não? Uma classe abstrata pode conter métodos abstratos e concretos, e uma classe não abstrata não pode conter métodos abstratos, seria isso?

Uma classe concreta não pode ter métodos abstratos.
Se houver um método abstrato dentro de uma classe, ela terá que ser obrigatoriamente abstrata.

Bem eu não sei muito sobre isso porque acho que essa área já é mais aplicada a quem projeta o sistema mesmo, e não a quem programa…

Mas vamos dizer que em algum sistema você tenha um método que as subclasses têm (obrigatoriamente) que ter, porque sem esse método não existe maneira de ser descendente de certa classe.
Vamos dizer: Animal. Todo Animal se alimenta certo? Então você podia colocar um método “public abstract void comer();” na classe Animal obrigando a qualquer tipo de animal, cachorro, zebra, girafa, etc, implementar o método “comer()”.

Não entendo muito disso ainda #).

Muito pelo contrário, é algo que quem programa deve saber, sem qualquer tipo de dúvida.

Você não pode instanciar objetos de uma classe Abstrata. Eles não fazem qualquer sentido, no nível daquela classe. Por exemplo, qual seria o som de um Animal genérico? Ou como você mandaria imprimir um Relatório genérico? Não faz qualquer sentido.

Mesmo que a classe não possua qualquer método abstrato (como é o caso da WindowAdapter, do próprio java), não faria sentido criar objetos dela. A WindowAdapter, por exemplo, é uma implementação da interface WindowListener com todos os métodos vazios. Instanciar um windowadapter seria ter na mão um objeto cheio de métodos que não fazem absolutamente nada. Por isso, apesar de ter tudo implementado, a classe foi marcada como abstrata, porque espera-se que o programador implemente pelo menos um de seus métodos.

Por isso, uma classe concreta não pode ter métodos abstratos. Esse é um requisito indispensável para que a classe seja completa. E, claro, uma classe completa deve representar um conceito concreto.

Do ponto de vista de projeto, tornar uma classe abstrata também significa dizer que ela foi feita para ser estendida. Ou seja, que houve preocupação, por parte do programador da classe, para que filhos dela possam ser criados sem violar muito os bons conceitos de OO. Muitos programadores, de fato, não se preocupam tanto assim nesse aspecto, o que introduz muitos bugs em sistemas.

Via de regra, prefira sempre acoplar classes do que usar herança. Embora herança seja um recurso válido, considere-o sempre como um dos últimos. Além disso, se for usa-la, procure tornar as classes onde será usada pequenas, e considere fortemente a possibilidade de ter uma interface, ao invés de uma superclasse, como o tipo mais alto da hierarquia.

Entendi alguma coisa, sei muito pouco ainda para absorver tudo, mas essas informações serão válidas futuramente, vlw galera =D