Conheça 6 tipos de polimorfismo

Victor Igor
Red Ventures Brasil - Tech
4 min readJan 16, 2017

Polimorfismo não tem nada a ver com OO-class-based! E não existe apenas 2 tipos de polimorfismo, que é o que a maioria das pessoas ensinam, não se preocupe se você não sabe o que é polimorfismo, tentarei lhe explicar de uma forma não acadêmica.

Introdução ao Polimorfismo

O assunto em si, não é muito claro para vários programadores, e algumas pessoas explicam de forma equivocada, mais adiante vai perceber o porquê. A princípio, polimorfismo quer dizer ‘várias formas’, pode-se dizer que é o ato do mesmo código suportar diversas coisas.

O foco aqui não é a implementação e sim no conceito, por tanto irei alternar no uso da linguagem para exemplos.

1. Subtyping

Esse é o polimorfismo que pode ser considerado entre os mais conhecidos, pois é o que muitos costumam dizer quando falam de ‘polimorfismo’. São subclasses que fornecem diferentes implementações de algum método da super classe.

2. Ad-hoc Polymorphism (Overloading)

Também conhecido como sobrecarga, você basicamente terá a execução do método de acordo com quantidade ou tipos de parâmetros da função, então dependerá do que for passado. Por exemplo:

3. Ad-hoc Polymorphism (Coercion polymorphism)

Acontece quando um tipo primitivo ou um objeto é ‘convertido’ em outro tipo de objeto ou tipo primitivo, e essas conversões podem ser implícitas(são feitas automaticamente) ou explicitada.

Coerções são essencialmente uma forma de abreviatura que pode reduzir o tamanho do programa e legibilidade do programa, mas também pode causar erros de sistema sutis e, por vezes, perigosos. Coerções é geralmente detectada no tempo de compilação, mas em linguagens impuras como LISP, têm abundância de coerções que são apenas detectado e executado em tempo de execução.

Um exemplo de Coerção bem comum é de um número ponto flutuante que pode ser usado aonde se espera um inteiro.

float b = 2; 
int a = 3.33; // implicitly coercion (coercion)
a = (int) 10.2; // explicitly coercion (casting)

4. Parametric Polymorphism

Também é chamado de Generics em Java e C#, e templates em C++. Diferente de Ad-hoc(overloading), basicamente é uma função ou um tipo de dado que pode ser escrito genericamente para que ele possa lidar com valores de forma idêntica sem depender do seu tipo. Generics pode ser feito tanto com estruturas ou classes, por exemplo:

Estrutura:

Classe:

Esse tipo de polimorfismo só ocorrem em linguagens tipadas, e não é tão comum em linguagens OO como Java e C#, e sim mais comum em linguagens funcionais como Haskell e OCaml.

5. Structural Polymorphism

Imagine uma função que executa em uma tal estrutura de um valor. Porém ela funciona para todos os valores que são super conjuntos dessa estrutura. Calma, você vai entender. Sei que pode parecer um pouco confuso sobre essa ‘estrutura de um valor’, vamos ver um exemplo:

class Airplane{
constructor(e::<Left>, s::<Top>, d::<Right>){
this.left<- e
this.top<- s
this.right<- d
}
}
interface Direction{
left: <Left>
right: <Right>
}
move(direc: Direcao<Int, Int>){
return direc.left- direc.right
}
move(new Airplane(5, 6, 2)) ;;=> 3
move(new Direction(3, 1)) ;;=> 3

Funcao 'mover' funciona para qualquer coisa com propriedades de direita e esquerda e não com um tipo específico.
Mas agora imagina você misturando com Overloading e criar outra função mover, porém esperando um <Int, Float> e criar um comportamento diferente.

A maioria das linguagens tipadas por serem de tipos nominais, elas não suportam esse tipo de polimorfismo, mas você pode fazer o uso de interfaces.

6. Row Polymorphism

Se você entender todos que já foram citados, esse você tira de letra! :) Imagine agora usar todo o poder do Structural Polymorphism com o Parametric Polymorphism! Intependente do tipo que a função mover receber, ela fará.

class Airplane{
constructor(e::<Left>, s::<Top>, d::<Right>){
this.left<- e
this.top<- s
this.right<- d
}
}
interface Direction{
left: <Left>
right: <Right>
}
mover(direc: Direction<X, Y>){
return direc.left - direc.right
}
mover(new Airplane(5, 6, 2)) ;;=> 3
mover(new Direction(3.5, 0.5)) ;;=> 3

Conclusão

É bem importante deixar claro que o ‘tipo’ que citei, é melhor interpretá-lo como “Algo que se parece com as propriedades que sua operação está esperando”, senão estaremos excluindo a possibilidade de polimorfismo nas linguagens com tipagem dinâmica.

Os nomes dos tipos que citei também podem ter nomes diferente e são até categorizados, pode-se dizer que até um ou outro é da subcategoria de outro.

Categorização de Cardelli: http://lucacardelli.name/papers/onunderstanding.a4.pdf

Existe muitos tipos de polimorfismo, alguns mais acadêmicos como Polytypism que já é um tipo especial de polimorfismo e que só tem em linguagens com Generalised Algebraic Datatypes (GADTs), e o F-bounded polymorphism, e nesse momento deve ter alguém inventando mais outro, então cuidado ao querer explicar polimorfismo para alguém, pois polimorfismo não tem nada a ver com OO-class-based, e sim com o conceito original de OO que é a troca de mensagens, pois é apenas a forma da mensagem ser recebida por objetos diferentes. Cabe agora você saber como a linguagem que você desenvolve implementa polimorfismo.

--

--