Saltar para o conteúdo

Polimorfismo (ciência da computação): diferenças entre revisões

Origem: Wikipédia, a enciclopédia livre.
Conteúdo apagado Conteúdo adicionado
Linha 2: Linha 2:
{{Mais-notas|data=dezembro de 2011}}
{{Mais-notas|data=dezembro de 2011}}
{{Orientação a objetos}}
{{Orientação a objetos}}
Na [[programação de computadores|programação]] [[Orientação a objetos|orientada a objetos]], o '''polimorfismo''' permite que referências de tipos de [[Classe (programação)|classes]] mais abstratas representem o comportamento das classes concretas que referenciam. Assim, é possível tratar vários tipos de maneira homogênea (através da interface do tipo mais abstrato). O termo '''''polimorfismo''''' é originário do [[Língua grega|grego]] e significa "muitas formas" (''poli'' = muitas, ''morphos'' = formas).
Na [[programação de computadores|programação]] [[Orientação a objetos|orientada a objetos]], o '''HUEHUEHUE''' permite que referências de tipos de [[Classe (programação)|classes]] mais abstratas representem o comportamento das classes concretas que referenciam. Assim, é possível tratar vários tipos de maneira homogênea (através da interface do tipo mais abstrato). O termo '''''HUEHUEHUE''''' é originário do [[Língua grega|grego]] e significa "muitas formas" (''poli'' = muitas, ''morphos'' = formas).


O polimorfismo é caracterizado quando duas ou mais classes distintas tem [[método (programação)|métodos]] de mesmo nome, de forma que uma função possa utilizar um [[objeto (programação)|objeto]] de qualquer uma das classes polimórficas, sem necessidade de tratar de forma diferenciada conforme a classe do objeto.<ref name="linuxtopia.python.polymorphism">[[Steven F. Lott]], ''A Programmer's Introduction to Python'', ''Building Skills in Python'', ''Part III. Data + Processing = Objects'', ''Chapter 22. Advanced Class Definition'', ''Polymorphism'' [http://www.linuxtopia.org/online_books/programming_books/python_programming/python_ch22s02.html <nowiki>[em linha]</nowiki>]</ref>
O HUEHUEHUE é caracterizado quando duas ou mais classes distintas tem [[método (programação)|métodos]] de mesmo nome, de forma que uma função possa utilizar um [[objeto (programação)|objeto]] de qualquer uma das classes polimórficas, sem necessidade de tratar de forma diferenciada conforme a classe do objeto.<ref name="linuxtopia.python.polymorphism">[[Steven F. Lott]], ''A Programmer's Introduction to Python'', ''Building Skills in Python'', ''Part III. Data + Processing = Objects'', ''Chapter 22. Advanced Class Definition'', ''Polymorphism'' [http://www.linuxtopia.org/online_books/programming_books/python_programming/python_ch22s02.html <nowiki>[em linha]</nowiki>]</ref>


Uma das formas de implementar o polimorfismo é através de uma [[classe (programação)|classe]] abstrata, cujos métodos são declarados mas não são definidos, e através de classes que [[herança (programação)|herdam]] os métodos desta classe abstrata.<ref name="trolltech">Documentação do software livre [[Qt]], ''Academic Solutions to Academic Problems'' [http://doc.trolltech.com/qq/qq15-academic.html <nowiki>[em linha]</nowiki>]</ref>
Uma das formas de implementar o HUEHUEHUE é através de uma [[classe (programação)|classe]] abstrata, cujos métodos são declarados mas não são definidos, e através de classes que [[herança (programação)|herdam]] os métodos desta classe abstrata.<ref name="trolltech">Documentação do software livre [[Qt]], ''Academic Solutions to Academic Problems'' [http://doc.trolltech.com/qq/qq15-academic.html <nowiki>[em linha]</nowiki>]</ref>


== Tipos de polimorfismo ==
== Tipos de HUEHUEHUE ==
Existem três tipos de polimorfismo que a linguagem pode ter (atente para o fato de que nem toda linguagem orientada a objeto tem implementado todos os tipos de polimorfismo):
Existem três tipos de HUEHUEHUE que a linguagem pode ter (atente para o fato de que nem toda linguagem orientada a objeto tem implementado todos os tipos de HUEHUEHUE):


* Universal
* Universal
** Inclusão - um ponteiro para classe prima do amigo pode apontar para uma instância de uma classe filha (exemplo em Java: <code>List lista = new LinkedList();</code> (tipo de polimorfismo mais básico que existe)
** Inclusão - um ponteiro para classe prima do amigo pode apontar para uma instância de uma classe filha (exemplo em Java: <code>List lista = new LinkedList();</code> (tipo de HUEHUEHUE mais básico que existe)
** Paramétrico - se restringe ao uso de templates que não é recomendado (C++, por exemplo) e generics (Java)
** Paramétrico - se restringe ao uso de templates que não é recomendado (C++, por exemplo) e generics (Java)
* Ad-Hoc
* Ad-Hoc
Linha 42: Linha 42:
</source>
</source>


O seguinte trecho de código demonstra o uso do polimorfismo:
O seguinte trecho de código demonstra o uso do HUEHUEHUE:


<source lang="Java">
<source lang="Java">
Linha 60: Linha 60:
</source>
</source>


Embora o método ''calcular'' tenha sido chamado duas vezes no interior de ''mostrarCalculo'', os tipos (isto é, as classes das instâncias) utilizados como parâmetros eram diferentes. De fato, o comportamento de cada tipo era exatamente oposto. É comum definir sobrecarga de métodos ou simplesmente [[sobrecarga]] como uma forma de polimorfismo (chamado de polimorfismo ad-hoc). Nesse caso, implementa-se métodos com um mesmo nome, mudando apenas a lista de parâmetros que ele recebe. Digamos
Embora o método ''calcular'' tenha sido chamado duas vezes no interior de ''mostrarCalculo'', os tipos (isto é, as classes das instâncias) utilizados como parâmetros eram diferentes. De fato, o comportamento de cada tipo era exatamente oposto. É comum definir sobrecarga de métodos ou simplesmente [[sobrecarga]] como uma forma de HUEHUEHUE (chamado de HUEHUEHUE ad-hoc). Nesse caso, implementa-se métodos com um mesmo nome, mudando apenas a lista de parâmetros que ele recebe. Digamos


<source lang="Java">
<source lang="Java">

Revisão das 10h59min de 27 de março de 2012

 Nota: Para outros significados, veja Polimorfismo (ciência da computação) (desambiguação).

Na programação orientada a objetos, o HUEHUEHUE permite que referências de tipos de classes mais abstratas representem o comportamento das classes concretas que referenciam. Assim, é possível tratar vários tipos de maneira homogênea (através da interface do tipo mais abstrato). O termo HUEHUEHUE é originário do grego e significa "muitas formas" (poli = muitas, morphos = formas).

O HUEHUEHUE é caracterizado quando duas ou mais classes distintas tem métodos de mesmo nome, de forma que uma função possa utilizar um objeto de qualquer uma das classes polimórficas, sem necessidade de tratar de forma diferenciada conforme a classe do objeto.[1]

Uma das formas de implementar o HUEHUEHUE é através de uma classe abstrata, cujos métodos são declarados mas não são definidos, e através de classes que herdam os métodos desta classe abstrata.[2]

Tipos de HUEHUEHUE

Existem três tipos de HUEHUEHUE que a linguagem pode ter (atente para o fato de que nem toda linguagem orientada a objeto tem implementado todos os tipos de HUEHUEHUE):

  • Universal
    • Inclusão - um ponteiro para classe prima do amigo pode apontar para uma instância de uma classe filha (exemplo em Java: List lista = new LinkedList(); (tipo de HUEHUEHUE mais básico que existe)
    • Paramétrico - se restringe ao uso de templates que não é recomendado (C++, por exemplo) e generics (Java)
  • Ad-Hoc
    • Sobrecarga - duas funções/métodos com o nome diferente mas assinaturas diferentes

Exemplos

Suponha a seguinte classe escrita em Java:

public abstract class OperacaoMatematica {
    public abstract double calcular(double x, double y);
}

Esta é uma classe abstrata que representa qualquer operação matemática. 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. Definamos então, duas subclasses, Soma e Subtracao, 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;
    }
}

O seguinte trecho de código demonstra o uso do HUEHUEHUE:

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
        Contas.mostrarCalculo(new Soma(), 5, 5); // Imprime o resultado é: 10

        // Depois uma subtração
        Contas.mostrarCalculo(new Subtracao(), 5, 5); // Imprime o resultado é: 0
    }
}

Embora o método calcular tenha sido chamado duas vezes no interior de mostrarCalculo, os tipos (isto é, as classes das instâncias) utilizados como parâmetros eram diferentes. De fato, o comportamento de cada tipo era exatamente oposto. É comum definir sobrecarga de métodos ou simplesmente sobrecarga como uma forma de HUEHUEHUE (chamado de HUEHUEHUE ad-hoc). Nesse caso, implementa-se métodos com um mesmo nome, mudando apenas a lista de parâmetros que ele recebe. Digamos

    public static void mostrarCalculo(Soma soma, double x, double y) {
        System.out.println("O resultado é: " + soma.calcular(x, y));
    }

    public static void mostrarCalculo(Subtracao subtracao, double x, double y) {
        System.out.println("O resultado é: " + subtracao.calcular(x, y));
    }

Embora nesse caso o resultado possa ser o mesmo que aquele obtido com o uso de herança, no polimorfismo ad-hoc não existem garantias que os métodos sobrecarregados tenham o mesmo comportamento.

Benefícios do polimorfismo

Clareza e manutenção do código

Em linguagens de programação não-polimórficas, para implementar o método mostrarCalculo, seria necessário recorrer a uma enumeração com o tipo de operação e, dentro do método, testar o valor da enumeração, como no exemplo abaixo:

public void mostrarCalculo(int operacao, double x, double y) {
    System.out.print("O resultado é: ");

    switch (operacao) {
        case SOMA: 
            System.out.print(x + y);
            break;
        case SUBTRACAO: 
            System.out.print(x - y);
            break;

        // Outras operações...
        default:
            throw new UnsupportedOperationException();
            break;
    }
}

Além do código ser maior e mais difícil de ler, essa implementação tem outros problemas. Provavelmente esse não será o único método a utilizar operações matemáticas e, portanto, pode-se esperar não um, mas vários switchs como esse pelo código. O que acontece, então, se uma nova operação for adicionada ao sistema? Será necessário que todos os switchs sejam encontrados e substituídos. Com o polimorfismo, a modificação restringiria-se apenas a criação de uma nova classe.

Aplicações flexíveis

O polimorfismo combinado à reflexão permite facilmente a criação de plugins. A aplicação original cria interfaces e classes que tem muito conhecimento semântico, mas a sua implementação efetiva ficará a cargo de terceiros. Uma aplicação gráfica, por exemplo, poderia ser implementada de forma a desenhar linhas, formas e gráficos precisos de acordo com operações matemáticas fornecidas. Enquanto isso, empresas terceiras, nos diversos campos de sua atuação, implementariam as operações matemáticas específicas para o seu empreendimento (cálculos de órbitas para astronomia, cálculos estruturais para engenharia civil, balística para aeronáutica, etc).

Polimorfismo e padrões de projeto

Boa parte dos padrões de projeto de software baseiam-se no uso de polimorfismo, por exemplo: Abstract Factory, Composite, Observer, Strategy, Template Method, etc.

O polimorfismo também é usado em uma série de refatorações, como substituir condicional por polimorfismo.[3]

Referências

  1. Steven F. Lott, A Programmer's Introduction to Python, Building Skills in Python, Part III. Data + Processing = Objects, Chapter 22. Advanced Class Definition, Polymorphism [em linha]
  2. Documentação do software livre Qt, Academic Solutions to Academic Problems [em linha]
  3. «Refactoring: Replace Conditional with Polymorphism». www.refactoring.com. Consultado em 10 de Março de 2011 

Ver também