Polimorfismo.pdf

Post on 28-Oct-2015

45 views 2 download

Transcript of Polimorfismo.pdf

UFG - Instituto de Informática

Curso: Ciências da Computação

Programação Orientada a ObjetosProf.: Fabrízzio A A M N Soaresprofessor.fabrizzio@gmail.com

Aula 16 – Polimorfismo

O que é polimorfismo?

A palavra polimorfismo vem do grego e significa que pode tomar várias formas.

Esta característica é um dos conceitos essenciais da programação orientada para o objeto.

Enquanto que a herança se refere às classes (e à sua hierarquia), o polimorfismo diz respeito aos métodos dos objetos.

Tipos de polimorfismo

Polimorfismo

Universal

Paramétrico

Ad-hoc

Inclusão Sobrecarga Coerção

Classificação segundo Cardelli e Wegner 1985.

Polimorfismo Ad-hoc

Não existe um modo único e sistemático de determinar o tipo de resultado de uma função em termos dos tipos dos seus argumentos de entrada.

É uma forma limitada de polimorfismo. Possui duas formas: coerção e sobrecarga.

Polimorfismo Universal

Trabalha potencialmente num conjunto infinito de tipos de modo disciplinado.

Possui duas formas: paramétrico e inclusão.

Polimorfismo de Coerção

Meio para contornar a rigidez dos tipos monomórficos.

Existe um mapeamento interno entre tipos. Exemplo:

Se o operador soma é definido como tendo 2 parâmetros reais e um inteiro e um real são passados como parâmetros, o inteiro é “coagido” para um real.

Polimorfismo de Sobrecarga

Permite que um nome de função seja utilizado mais do que uma vez com diferentes tipos de parâmetros.

Exemplo: Uma função soma pode ser sobrecarregada para

operar com dois parâmetros inteiros e dois reais.

Polimorfismo Paramétrico

Uma única função é codificada e ela trabalhará uniformemente num intervalo de tipos. Funções paramétricas também são chamadas

de funções genéricas. Exemplo:

Templates em C++ Generics em Java

Polimorfismo de Inclusão

É encontrada somente em linguagens orientadas a objetos e

está relacionada com a noção de subtipo. Exemplo:

Hierarquia de classes.

Polimorfismo

Em Java, por exemplo, temos o Polimorfismo de coerção; Polimorfismo paramétrico (através do uso de

identificador entre os sinais de maior e menor <>);

Polimorfismo de sobrecarga e Polimorfismo de inclusão.

Exemplo de Polimorfismo de inclusão

Suponhamos o seguinte exemplo:

public abstract class OperacaoMatematica {

public abstract double calcular(double x, double y);

}

Esta é uma classe abstrata que representa qualquer operação matemática.

Exemplo de Polimorfismo de inclusão

Podemos imaginar diversas operações que se encaixam na sua interface, como soma, subtração, multiplicação ou divisão, entre outras.

Note que, mesmo que a natureza do cálculo mude, a semântica do método calcular não muda, ou seja, ele sempre calculará o resultado da operação matemática que está sendo trabalhada.

Exemplo de Polimorfismo de inclusão

Definamos então, duas subclasses, Soma e Subtração, que implementam a classe OperacaoMatematica:

public class Soma extends OperacaoMatematica { public double calcular(double x, double y) { return x+y; }} public class Subtracao extends OperacaoMatematica { public double calcular(double x, double y) { return x-y; }}

Exemplo de Polimorfismo de inclusão

O seguinte trecho de código demonstra sem o polimorfismo:public class Contas { public static void main(String args[]) {

//Primeiro calculamos uma soma Soma sum = new Soma(); System.out.println("O resultado é: + sum.calcular(5, 5));

//Depois uma subtração Subtracao dif = new Subtracao(); System.out.println("O resultado é: + dif.calcular(5, 5)); }}

Problema

Como faríamos para passar o objeto para uma função que irá realizar as operações para nós?

Precisaríamos criar um método para tratar cada objeto!

Continuação do exemplo

Possível solução (sem polimorfismo):public class Contas { public static void mostrarCalculoSoma(Soma operacao, double x, double y) { System.out.println("O resultado é: " + operacao.calcular(x, y)); } public static void mostrarCalculoSub(Sub operacao, double x, double y) { System.out.println("O resultado é: " + operacao.calcular(x, y)); } public static void main(String args[]) { //Primeiro calculamos uma soma Soma sum = new Soma(); Contas.mostrarCalculoSoma(sum, 5, 5); //Imprime o resultado é: 10 //Depois uma subtração Subtracao dif = new Subtracao(); Contas.mostrarCalculoSub(dif, 5, 5); //Imprime o resultado é: 0 }}

Exemplo

O seguinte trecho de código demonstra com o polimorfismo:public class Contas { public static void main(String args[]) {

//Primeiro calculamos uma soma OperacaoMatematica sum = new Soma(); System.out.println("O resultado é: + sum.calcular(5, 5));

//Depois uma subtração OperacaoMatematica dif = new Subtracao(); System.out.println("O resultado é: + dif.calcular(5, 5)); }}

Continuação do Exemplo

Assim, se quiséssemos passar para uma função realizar as operações poderíamos fazer:

public class Contas { public static void mostrarCalculo(OperacaoMatematica operacao, double x,

double y) { System.out.println("O resultado é: " + operacao.calcular(x, y)); } public static void main(String args[]) { //Primeiro calculamos uma soma Soma sum = new Soma(); Contas.mostrarCalculo(sum, 5, 5); //Imprime o resultado é: 10 //Depois uma subtração Subtracao dif = new Subtracao(); Contas.mostrarCalculo(dif, 5, 5); //Imprime o resultado é: 0 }}

Exemplo com animais

Para não perdermos o velho costume, vamos a exemplos com animais!

Temos três classes, Animal, Cachorro, Cobra. Analisando podemos perceber que Cachorro e

Cobra são animais, más com características diferentes.

Exemplo locomover O cachorro anda com suas quatro patas e a cobra

se rastejando.

Exemplo com animais

Vamos ao código

Classe Animal:

public abstract class Animal {

public abstract String andar();

}

Vamos ao código

Classe Cachorro:

public class Cachorro extends Animal {

public String andar(){

return ("Cachorro: se locomove com

quatro patas");

}

}

Vamos ao código

Classe Cobra:

public class Cobra extends Animal {

public String andar(){

return ("Cobra: se locomove rastejando");

}

}

Vamos ao código

Programa para testar as classes/objetos polimórficos:

public class Polimorfismo { public static void main(String args[]){ Animal anim [] = new Animal[2]; anim[0] = new Cachorro(); anim[1] = new Cobra(); for (int i=0;i < anim.length;i++){ System.out.println(anim[i].andar()); } }}

Observações sobre o polimorfismo de inclusão

Toda classe que pode se comportar como qualquer uma de suas ancestrais

Quando se usa polimorfismo não se muda o tipo do objeto.

Ele nasce de um tipo e morre do mesmo tipo. O que se trocou foi sua casca (interface)

Observações sobre o polimorfismo de inclusão

Quando se atribui um objeto a uma variável de um tipo ancestral, você terá um comportamento polimórfico

Mas o contrário não é verdade. Por via de regra, não se pode atribuir um objeto a

um tipo sucessor

Pessoa p = new PessoaFisica() // ok

PessoaFisica pf = new Pessoa() // errado

Observações sobre o polimorfismo de inclusão

Quando se atribui um objeto a uma variável de um tipo ancestral, você terá um comportamento polimórfico

Mas o contrário não é verdade. Por via de regra, não se pode atribuir um objeto a

um tipo sucessor

Pessoa p = new PessoaFisica() // ok

PessoaFisica pf = new Pessoa() // errado

Observações sobre o polimorfismo de inclusão

Se você tiver um objeto de um tipo e está usando a casa (interface) de seu ancestral, não será possível acessar os métodos e atributos do objeto original.

Pessoa p = new PessoaFisica(“111.111.111-11”);

String cpf = p.getCPF(); //errado

Observações sobre o polimorfismo de inclusão

Porém, se você tiver certeza que o objeto é de um tipo, você pode forçar um “Casting”.

Pessoa p = new PessoaFisica(“111.111.111­11”);String cpf = (PessoaFisica)p.getCPF(); // ok

ouPessoa p = new PessoaFisica(“111.111.111­11”);PessoaFisica pf = (PessoaFisica)p;String cpf = pf.getCPF(); // ok