Polimorfismo em java

Preview:

DESCRIPTION

Este slide mostra os principais conceitos do polimorfismo na linguagem Java.

Citation preview

Polimorfismo em Java

Manoel Afonso Pereira de Lima Filho10088000901

POOUFPa – 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 fizermosGato gt = (Gato) pets[0];

teremos uma referência a um Gato?

Referências polimórficas

● Se fizermosGato 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.

Recommended