A conversão do filho para o pai é sempre possível.
Isso porque, o filho, obrigatóriamente, tem todos os métodos do pai. O que acontece, é que vc acaba com uma variável que usa o filho de maneira simplificada. Mas correta.
Veja o exemplo:
[code]public abstract class Animal {
public abstract String barulho();
}
public class Cachorro extends Animal {
public String barulho() { return “auau!”; }
public void farejar() { //Fareja algo }
}
public class Cachorro extends Gato {
public String barulho() { return “miau!”; }
public void lamberOProprioCorpo() { //Toma banho }
}[/code]
Uma possível função que imprimisse o barulho de um animal qualquer na tela seria:
public void imprimeBarulho(Animal animal) {
System.out.println(animal.barulho());
}
Veja, para a função, não interessa que os animais mais específicos tenham outros métodos. O que interessa é que todo animal, seja um cachorro, gato, papagaio ou galinha faz barulho. Como todo animal respeita a interface da classe pai, e implementa os métodos do pai, podemos, com certeza, dizer que enxergar um Gato ou Cachorro como um animal “qualquer” é possível.
Lembrando da relação de herança: Todo Cachorro é um Animal. Todo gato é um Animal.
Por outro lado, o oposto não é correto. Se temos em mãos um animal “qualquer”:
Animal animal = leAnimal();
Podemos fazer:
Gato gato = animal;
?
Não. Aquele animal poderia ser um cachorro. Embora todo gato seja um animal, nem todo animal é um gato.
E então, estaríamos fazendo uma conversão errada de tipos. Aí está a insegurança da operação.
O que acontece é que as vezes você tem certeza de que o animal em questão é mesmo um gato. Então, o Java fornece uma maneira do programador dizer isso e forçar a conversão. Essa maneira é o downcast, usando o operador explícito:
if (animal instanceof Gato) {
Gato gato = (Gato) animal;
//Estou dizendo para o Java. Ei, tenho certeza, faça a conversão.
}
E se não for um gato, e ainda sim vc usar o cast? Vai receber uma ClassCastException.
Espero não ter te confundido mais.