Polimorfismo, Interfaces, Classes Abstractas/Exemplos Simples de Herança em Java
From Wiki**3
(Redirected from Exemplos Simples de Herança em Java)
Os seguintes exemplos estão escritos em Java.
Hierarquia de Classes
As seguintes classes descrevem uma hierarquia: o conceito mais abstracto é o de animal, seguido de mamífero, seguido de gato (o conceito mais específico).
- Todas as classes definem o método
nadar. Este método é definido em todas as classes pois admitiu-se que cada tipo de animal tem uma forma especial de nadar. - Apenas a classe
Animaldefine o métodoirPara. Este método é definido comofinalpois admitiu-se que é suficientemente genérico para todos os animais. - Apenas a classe
Gatodefine o métodomiar(a acção não é suficientemente geral para ser definida a um nível superior).
Class "Animal"
A definição da classe Animal é como se segue:
class Animal {
final void irPara(int p) {
System.out.println("Animal: deslocação para " + p);
}
void nadar() {
System.out.println("Animal: nadar");
}
}
Class "Mamífero"
A definição da classe Mamífero é como se segue:
class Mamífero extends Animal {
void nadar() {
System.out.println("Mamífero: nadar");
}
}
Class "Gato"
A definição da classe Gato é como se segue:
class Gato extends Mamífero {
void nadar() {
System.out.println("Gato: nadar");
}
void miar() {
System.out.println("Gato: miar");
}
}
No exemplo seguinte demonstra-se um caso simples de polimorfismo assim como de binding. O exemplo de polimorfismo pode ser observado na iniciação da referência animal: em lugar de referenciar um objecto da classe Animal, referencia um objecto da classe Gato. Este procedimento é admissÃvel para quaisquer referências e objectos, desde que o tipo associado à referência esteja ao mesmo nível hierárquico, ou acima, que o tipo associado ao objecto (i.e., seria admissÃvel a uma referência do tipo Animal referenciar um objecto do tipo Mamífero ou uma do tipo Mamífero referenciar um objecto do tipo Gato).
O conceito de binding pode ser observado na selecção dos métodos irPara (early binding) e nadar (late binding).
A simple application
Test class
public class Teste {
public static void main(String[] args) {
Animal animal = new Gato();
Gato gato = new Gato();
animal.irPara(22); // irPara é final em Animal: early binding
animal.nadar(); // nadar é seleccionado durante a execução: late binding
//animal.miar(); // Erro de compilação: não há miar em Animal
((Gato)animal).miar(); // downcast
gato.irPara(33);
gato.nadar();
gato.miar();
}
}
Result
O resultado é o seguinte:
Animal: deslocação para 22 Gato: nadar Gato: miar Animal: deslocação para 33 Gato: nadar Gato: miar
Note-se que, no late binding, é o tipo do objecto e não o da referência que determina o método a invocar. No early binding, i.e., para métodos final (recorde-se que métodos private são implicitamente final) e static, é o tipo da referência que define o método a invocar (em tempo de compilação). Veja-se o exemplo seguinte.
Polymorphic Application
O aspecto da selecção do método a executar através de late binding é importante na medida em que contribui para a uniformização do código.
Test application
No exemplo seguinte, a invocação de nadar é efectuada uniformemente.
class Teste {
public static void main(String[] args) {
Animal[] v = { new Animal(), new Mamífero(), new Gato() };
for (Animal a: v) a.nadar();
}
}
Result
O resultado é o seguinte:
Animal: nadar Mamífero: nadar Gato: nadar
Como se pode apreciar, o vector contém referências para animais não especificados. No entanto, a invocação do método nadar é feita de acordo com a classe do objecto.
Polymorphism and Downcasts
Test application
Considere-se agora a aplicação de downcasts:
class Teste {
public static void main(String[] args) {
Animal[] v = { new Animal(), new Mamífero(), new Gato() };
// v[0].miar(); // erro de compilação
// v[1].miar(); // erro de compilação
// v[2].miar(); // erro de compilação
// ((Gato)v[0]).miar(); // excepção ClassCastException (erro durante a execução)
// ((Gato)v[1]).miar(); // excepção ClassCastException (erro durante a execução)
((Gato)v[2]).miar();
}
}
Problems at execution time
A execução de downcasts inválidos, i.e., conversão para tipos incompatíveis (como se pode observar na linhas 7 e 8 do exemplo), implica a ocorrência de erros em tempo de execução.
Erro de execução, caso o primeiro cast fosse descomentado:
Exception in thread "main" java.lang.ClassCastException: Animal
at Teste.main(Teste.java:7)
Erro de execução, caso o segundo cast fosse descomentado:
Exception in thread "main" java.lang.ClassCastException: Mamífero
at Teste.main(Teste.java:8)
Result (without errors)
Resultado sem erros:
Gato: miar