Enviado por Do utilizador5541

polimorfismoemjava-111209122842-phpapp02

Propaganda
Polimorfismo em Java
Manoel Afonso Pereira de Lima Filho
10088000901
POO
UFPa – Novembro – 2011
Tópicos
●
Introdução
●
Exemplo de polimorfismo
●
Herança
●
Classes abstratas
●
Referências polimórficas
●
Contrato
●
Interface
●
Considerações finais
Introdução
●
●
A herança é só o começo do polimorfismo.
O polimorfismo fornecerá mais flexibilidade,
clareza e facilidade de manutenção do código.
●
O principal personagem é a interface.
●
Permite a “programação no geral”.
Instanciando um objeto
●
1- Especifique o tipo:
Cao
●
2- Dê um nome a variável:
Cao fido
●
3- Aloque espaço ao objeto:
Cao fido new Cao();
●
4- Conecte a instância à variável:
Cao fido = new Cao();
Tipos de polimorfismo
●
●
●
Polimorfismo de Inclusão:
Animal an = new Gato();
Polimorfismo Paramétrico:
List<Animal> a = new ArrayList<Animal>();
Polimorfismo de sobrecarga:
public int soma(int a, int b);
public int soma(int[] nums);
Exemplo de Polimorfismo
●
●
●
●
Suponha que as classes Cao, Gato e Passaro
estendem a classe Animal.
Suponha que Animal tenha um método
chamado barulho().
O polimorfismo ocorre quando o programa
invoca um método por uma variável da
superclasse e a versão correta da subclasse é
chamada.
Assim, cada animal emitirá o seu som
peculiar.
Herança
●
●
Um dos benefícios da herança é que podemos
evitar códigos duplicados os agrupando em
uma única classe.
Podemos sobrescrever os métodos que
devem ser mais específicos.
Árvore de herança
Árvore de herança
●
●
É permitido:
Gato meuGato = new Gato();
Animal meuCao = new Cao();
Faz sentido instanciar um animal?
Animal anim = new Animal();
Árvore de herança
●
●
Como Animal não é específica o suficiente,
ela não deve ser instanciada.
Assim, basta torná-la abstrata:
abstract class Animal {
…
}
Classes abstratas
●
●
Não é possível instanciá-las, é um erro de
compilação. Exemplo:
Animal a = new Animal(); //Errado
Podemos instanciar apenas as suas classes
concretas.
Animal b = new Gato(); //Correto
Classes abstratas
●
●
●
Definem apenas parte da implementação, isto
é, métodos que ainda podem ser úteis para as
subclasses.
Se um método não for genérico o bastante,
então o torne abstrato:
public abstract void mover();
Métodos abstratos não têm corpo e se uma
classe possuir algum método abstrato, ela
deverá ser abstrata também.
Por que usar abstract?
●
●
Não faz sentido uma classe abstrata possuir
todos os métodos implementados porque esse
código genérico não será útil para as
subclasses.
Abstract apenas define o modelo do objeto.
Por que usar abstract?
●
●
●
Poderemos, então, usar um tipo da
superclasse como argumento, tipo de retorno
ou tipo de matriz de um método.
Será fácil criar novos subtipos sem ter que
reescrever ou adicionar novos métodos para
lidar com esses novos tipos.
Protocolo de um método abstrato:
“Todos os subtipos desse tipo têm ESSE
método.”
Por que usar abstract?
●
Sem um modelo, teríamos de fazer isso para
um método fazer os animais emitirem sons:
public void somAnimal ( Cachorro c ) {…}
Por que usar abstract?
●
Sem um modelo, teríamos de fazer isso para
um método fazer os animais emitirem sons:
public void somAnimal ( Cachorro c ) {…}
public void somAnimal ( Gato g) {…}
Por que usar abstract?
●
●
Sem um modelo, teríamos de fazer isso para
um método fazer os animais emitirem sons:
public void somAnimal ( Cachorro c ) {…}
public void somAnimal ( Gato g) {…}
public void somAnimal ( Passaro p) {…}
E quanto mais classes surgirem, mais
sobrecarga haverá!
Por que usar abstract?
●
Com um modelo, faríamos apenas isso:
public void somAnimal ( Animal c ) {…}
●
Pois todos os animais emitem som, cada um a
seu modo.
Classes abstratas
●
●
●
Lembre-se que um método abstrato não tem
corpo.
Você deverá dar um na primeira subclasse
concreta.
Por exemplo, a classe concreta Passaro deve
implementar todos os métodos abstratos de
Animal.
Referências polimórficas
●
●
●
Ocorre quando uma superclasse “aponta”
para um dos seus subtipos.
Object pets[] = new Object[3];
pets[0] = new Cao();
pets[1] = new Gato();
pets[2] = new Passaro();
Vantagem: Um mesmo array armazena vários
tipos.
Desvantagem: quais métodos pets[1] tem?
Referências polimórficas
Apenas métodos de Object!
Referências polimórficas
●
Para usarmos os métodos específicos, temos
que converter o objeto para o seu tipo mais
específico. Assim:
Gato gt = (Gato) pets[1];
nos dará uma referência ao “gato que está
dentro do objeto”.
Referências polimórficas
●
Se fizermos
Gato gt = (Gato) pets[0];
teremos uma referência a um Gato?
Referências polimórficas
●
Se fizermos
Gato gt = (Gato) pets[0];
teremos uma referência a um Gato?
●
●
Não! Pois pets[0] foi instanciado como um
Cao.
Isso irá gerar em tempo de execução uma
exceção ClassCastException.
Referências polimórficas
●
Caso você não tenha certeza do tipo, use a
palavra reservada instanceof.
Contrato
●
●
●
As classes Cao, Gato e Passaro são
subclasses de Object.
A classe Object não define nenhum contrato
com as nossas classes.
Por isso temos que saber de antemão quem é
quem antes de fazer a conversão.
Interface
●
●
●
Interfaces são classes 100% abstratas.
A interface irá definir o contrato entre as
classes, isto é, o comportamento mínimo que
elas possuem.
Assim, você define funcionalidades que outras
classes podem obter, independentemente da
sua árvore de herança.
Interface
●
A interface Animal:
Interface
●
Uma classe concreta (Cao).
Interface
Interface
●
Com um contrato feito, vamos fazer um array
polimórfico:
Interface
●
Cada posição do array já é de fato um Cao, um
Gato e um Passaro.
Interface
●
Cada posição do array já é de fato um Cao, um
Gato e um Passaro.
Cada chamada é executada de acordo com o
tipo real!
Interface
●
Outro exemplo:
Interface
●
É garantido que o retorno é uma classe
concreta de Animal.
Interface
●
●
Até agora, vimos como interfaces ajudam a
tornar o programa mais simples.
Vamos ver como elas podem tornar o
programa flexível.
Interface
●
●
●
●
Temos a interface Animal e suas três
subclasses.
Todas com um contrato feito: animais emitem
som e se movem.
Suponha que queiramos agora que apenas os
cães sejam capazes de correr em uma
competição.
Isso quer dizer que temos de mudar o
contrato.
Interface
●
●
●
Não podemos adicionar um método correr()
na classe Animal pois afetaria a todos.
Poderíamos adicionar o método diretamente
na classe Cao!
Mas perderíamos qualquer relação entre um
cão corredor e um humano corredor (atleta).
Interface
●
Veja o diagrama de classes para pessoas:
Interface
●
Ora, se um cão corredor e um atleta tem algo
em comum, as duas classes poderiam
estender uma classe chamada Corredor.
Interface
Interface
Interface
●
Herança múltipla é proibido em Java!
●
Usaremos uma interface.
Interface
Interface
●
●
Agora criamos uma “conexão” entre duas
classes de árvores de herança distintas.
Podemos pensar nisso como “adicionar a
funcionalidade de correr” ao cão e ao atleta.
Interface
●
Assim, podemos criar um método que faça
com que os que correm, corram.
public void fazerCorrer(Corredor c) {…}
●
Não importa de qual árvore de herança os
objetos pertencem, pois sabemos que os que
vierem poderão correr.
Quando usar
●
●
●
Crie uma classe que não estenda nada
(exceto Object) quando esta não passar no
teste do É-UM.
Cria uma subclasse para ter uma versão mais
específica de uma classe.
Crie uma classe abstrata para ter um modelo
para suas subclasses, com algum código
implementado.
Quando usar
●
●
Crie uma interface para adicionar
funcionalidades a uma classe.
Assim, qualquer classe pode usar um
interface, independentemente de sua árvore
de herança.
Conclusão
●
●
●
Classes abstratas fornecem reuso de código,
mas são genéricas demais para serem
instanciadas.
Interfaces são classes 100% abstratas e criam
o contrato com todos os seus subtipos.
As interfaces fornecem uma ampla
flexibilidade para uso em tipos de retorno,
parâmetro ou de matriz.
Download