Este artigo abordará um dos mais poderosos recursos de programação, item essencial na bagagem técnica de todo bom desenvolvedor: o polimorfismo. Abordaremos, ao longo do texto, os conceitos que caracterizam as quatro técnicas existentes, dando ao leitor o conhecimento necessário para entender como o recurso é aplicado nas bibliotecas e plataformas que utiliza no seu dia-a-dia, bem como de aplicar nas suas próprias implementações.
Em que situação o tema é útil:
Este tema é útil para todo profissional que atue no desenvolvimento de soluções computacionais, principalmente aquelas desenhadas sob a luz do paradigma da orientação a objetos, em que o recurso do polimorfismo pode ser utilizado em sua plenitude. Embora praticamente todos os exemplos do artigo tenham sido desenvolvidos em Java, os conceitos e técnicas demonstrados podem ser aplicados em qualquer linguagem de programação orientada a objetos. Algumas técnicas de polimorfismo que veremos, como a de sobrecarga, podem inclusive ser adotadas em linguagens que não seguem o paradigma da orientação a objetos.
Resumo DevMan:
Muito se fala sobre polimorfismo e sua importância para sistemas construídos, principalmente, sobre o paradigma da orientação a objetos. Entretanto, o foco dado a este conceito tão importante é, geralmente, parcial, e nem todas as técnicas são conhecidas na profundidade necessária por uma parcela significativa de desenvolvedores. Este artigo apresentará de forma um pouco mais ampla cada um dos quatro formatos em que este conceito se apresenta, com exemplos práticos que complementam toda a teoria.
Polimorfismo é um termo que se originou do grego e significa “várias formas”. A semântica do mesmo é preservada quando transportado para o universo da programação de computadores. Através de técnicas que veremos ao longo do artigo, é possível que criemos estruturas suficientemente genéricas ao ponto de serem utilizadas em vários contextos, tornando o código-fonte final mais enxuto, legível e manutenível.
Embora possamos observar polimorfismo também em linguagens estruturadas, é no paradigma orientado a objetos que o conceito realmente ganha força e é aplicado em sua plenitude. Inúmeros padrões de projeto se beneficiam desta técnica, dentre os quais podemos destacar o Abstract DAO, Abstract Factory, Template Method, Strategy, Observer e Composite (para mais detalhes sobre Design Patterns, veja a seção Links). Mecanismos de tratamento de exceções e eventos em praticamente todo framework, bem como o desenvolvimento de plug-ins, são itens altamente beneficiados pelo emprego das técnicas polimórficas. De Swing/AWT a GWT e JavaServer Faces, passando por JPA, Hibernate, Struts, Spring e tantos outros, encontramos polimorfismo por todos os lados.
Não é raro encontrarmos, em fóruns renomados da web, profissionais de Tecnologia da Informação buscando explicações mais detalhadas a respeito do polimorfismo e recebendo respostas como a transcrita a seguir, retirada de um desses canais: “polimorfismo é polimorfismo, não existem tipos de polimorfismo”; motivação suficiente para a escrita deste artigo, em que abordaremos todas as características e roupagens deste conceito fundamental.
O polimorfismo é classificado em duas categorias, sendo que cada uma se ramifica em duas técnicas. Veremos, neste artigo, exemplos da aplicação de cada uma, seguida de uma discussão a seu respeito. Esperamos que o leitor tenha uma experiência construtiva durante a leitura deste material, reciclando conceitos e aprendendo outros, levando para o seu dia-a-dia todas as práticas aqui abordadas.
Antes de iniciarmos, verifique a Tabela 1, que resume as quatro abordagens existentes, tratadas a seguir em maiores detalhes. Todo o código será apresentado em Java (salvo uma das vertentes da técnica de polimorfismo por sobrecarga, que será exibida em C++), embora possam ser facilmente aplicadas a outras linguagens orientadas a objetos, como Objective-C ou C#.
Abordagem |
Descrição |
Coerção |
Atribuição forçosa de tipo a objetos recuperados em tempo de execução. Técnica conhecida também por Casting |
Sobrecarga |
Métodos com mesmo nome e assinaturas diferentes, podendo ter comportamentos totalmente distintos entre si |
Parametrização |
Através de modelos comportamentais, associa um conjunto variável de tipos de objetos a um padrão determinado |
Inclusão |
Através de uma referência para interfaces ou classes-mãe, é possível abordar um conjunto amplo de tipos de objetos |
Tabela 1. Resumo das quatro principais técnicas de polimorfismo.
O polimorfismo ad hoc
A tradução literal para o termo ad hoc, que tem sua origem no latim e é tão utilizado por profissionais de computação, é “para isto” ou, ainda, “para esta finalidade”. Na prática, o termo é usado para tudo aquilo que foi projetado para atender a uma demanda pontual, não genérica. Em outras palavras, técnicas ad hoc serão sempre aquelas para ataque a necessidades pontuais.
Esta categoria abrange duas técnicas, que são conhecidas como coerção (também chamado de casting) e sobrecarga. Ao longo desta seção, exploraremos cada uma em maiores detalhes.
Polimorfismo por coerção
O significado literal do termo coerção, na língua portuguesa, é ato ou efeito de obrigar/forçar. E é exatamente isto que acontece quando empregamos esta técnica no desenvolvimento de sistemas computacionais: forçamos um objeto a “vestir” uma roupagem específica. Isto é muito comum em casos em que precisamos definir um modelo genérico que seja, depois, redefinido/ especializado por outras classes de objetos. Para que isso seja possível, o template/padrão é construído utilizando apenas tipos suficientemente abstratos (a partir de interfaces ou ainda classes abstratas), do qual se derivam/especializam diversos tipos de objetos de acordo com a necessidade.
...