Vamos conversar sobre Polimorfismo?

Boa tarde galera, como vocês estão?

Estou atualmente estudando o conceito de Polimorfismo e estou utilizando a linguagem Java como meio de testes.

-> Ouvi dizer por ai, que os tipos de polimorfismo e suas quantidades podem variar de acordo com a linguagem de programação que você utiliza…

Enfim, estudando polimorfismo descobri alguns conceitos legais que a orientação a objetos pode te oferecer e que na maioria das vezes pode sim facilitar (e muito) a sua vida (desde que bem aplicado, é claro).

Polimorfismo é a capacidade que um método tem de possuir diversos comportamentos (implementações) de acordo com o contexto à qual está associado (no caso, a classe que o possui).

Eu acho importante separar alguns conceitos:

1. Assinatura do método: quantidade de parâmetros e seus tipos;
2. Cada classe só pode ter 1 (um) mesmo método (mesmo nome) com a mesma assinatura.

Nesse caso, é comum vermos alguns “tipos” de polimorfismo. São eles:

1. POLIMORFISMO DE SOBREPOSIÇÃO: uma super-classe possui um método abstrato/não-abstrato que pode ser sobreposto/sobrescrito por uma sub-classe/classe herdeira desta. Isso permite que um mesmo método tenha diferentes comportamentos de acordo com o seu contexto e classe que o possui. (Isso também se aplica à Interfaces e a classes abstratas???)

2. POLIMORFISMO DE SOBRECARGA: uma mesma classe pode ter um mesmo método (mesmo nome) com diferentes assinaturas. Esse conceito é chamado de sobrecarga de métodos. A quantidade e os tipos de parâmetros de cada assinatura do método sobrecarregado ditarão o comportamento/implementação que o mesmo deverá ter/realizar.

3. POLIMORFISMO PARAMÉTRICO: permite escrever métodos que recebam como parâmetros (ou retornem) objetos que possuem uma mesma super-classe (tanto direta, quanto indiretamente). -> funciona como um contrato. Assim, eu recebo qualquer classe que implemente a classe X tendo a segurança de que todas as sub-classes da classe X possuirão o(s) método(s) que interessa para o método primeiro. Em síntese, eu só preciso me preocupar com os métodos que preciso da super-classe e só receberei como parâmetros objetos que possuem determinados métodos.

Ao meu ver:

-> Polimorfismo de sobreposição: método abstrato/não-abstrato com apenas 1 assinatura na super-classe. Uma nova implementação deve ser realizada em sub-classes. Cada sub-classe só deve implementar este método 1 (uma) vez.

-> Polimorfismo de sobrecarga: método abstrato/não-abstrato que possui várias assinaturas em uma mesma classe.

-> Acredito que pode sim haver o polimorfismo de sobreposição, o de sobrecarga e o paramétrico ao mesmo tempo.

O que vocês acham? Acrescentariam mais algum conhecimento ou curiosidade? Acham que falei muita abobrinha? Esse é o momento de conversarmos sobre polimorfismo!

Encontrei uma discussão interessante do usuário dudu795 aqui no fórum do GUJ: Discussão sobre polimorfismo

E não esqueçam, fiquem em casa! :slight_smile:

Isto está errado. Polimorfismo não tem a ver com métodos, mas sim com objetos.

Polimorfismo é a capacidade de um objeto (uma instancia de uma classe) de se comportar como se fosse de outro tipo (uma superclasse ou superinterface).

Então sobrecarga e sobreescrita de métodos são recursos que a linguagem te oferece para projetar suas classes e são influenciadas pelo comportamento polimorfico dessas classes, mas só.

Isto está errado. Vc tratou nome e assinatura de um método como coisas diferentes quando, na verdade, o nome faz parte da assinatura, veja aqui: https://docs.oracle.com/javase/specs/jls/se14/html/jls-8.html#jls-8.4.2

Já sobre polimorfismo parametrico, da forma como o entendo, tem a ver com Generics.

Eu tenho esse compilado…

26.3 POLIMORFISMO
Lexicalmente, o polimorfismo é a situação em que algo pode se apresentar sob diferentes formas. Na programação, significa que um único nome pode identificar códigos diferentes, devendo haver, portanto, algum mecanismo automático para selecionar o código correto para o contexto. Assim, um mesmo nome pode expressar comportamentos diferentes.

# Linguagem polimórfica : é qualquer linguagem de programação que suporta o polimorfismo. De modo contrário, uma linguagem que não suporte esse mecanismo, é dita linguagem monomórfica .

# Variável polimórfica : é qualquer variável que pode conter muitos tipos diferentes.

26.3.1 Tipos de Polimorfismo

Basicamente, do ponto de vista do tempo de ocorrência da seleção do código correto. Com efeito, o polimorfismo pode ser ad-hoc ou universal .

Um polimorfismo é dito ad-hoc quando ocorre em tempo de compilação . O termo em latim ad-hoc indica que algo que é feito para um fim determinado. De fato, por ser selecionado em tempo de compilação, é um polimorfismo que requer que o programador codifique de forma que haja a possibilidade de seleção de código por parte do compilador.

O polimorfismo ad-hoc subdivide-se em polimorfismo de sobrecarga e polimorfismo de coerção . Como característica comum, têm o fato de serem limitados (número finito) o número de variações de código que um mesmo nome pode representar.

Por outro lado, o polimorfismo apresentam como característica o fato de serem ilimitados, ou seja, uma indefinição na quantidade de variações de código que um mesmo nome pode representar. Portanto, apresentam um número infinito de variações de código para um mesmo nome.

O polimorfismo universal sempre ocorrem em tempo de execução e são o tipo de polimorfismo por excelência.

Esse tipo de polimorfismo baseia-se no conceito de ligação tardia ( late binding ) e é determinado pelo princípio da substituição de Liskov (PSL).

A ligação tardia descreve a situação em que o compilador não gera o código “correto” em tempo de execução (ligação tardia), mas o faz quando o método é chamado por um objeto. Assim, pode examinar algumas características do objeto chamador e dos métodos disponíveis e definir qual código gerar. Esse procedimento é denominado de ligação dinâmica (define o código correto quando é necessário).

O princípio da substituição de Liskov, enuncia que “ Se S é um subtipo de T, então, os objetos do tipo T podem ser substituídos pelos objetos de tipo S sem que seja necessário alterar as propriedades do programa .”. Logo, esse princípio define o que se chama de capacidade de substituição/conexão de uma hierarquia de classes. Como as classes criam tipos, na herança, as subclasses criam subtipos. Logo, somente linguagens que suportem a herança é que podem prover esse tipo de polimorfismo.

O polimorfismo universal pode ser paramétrico ou de sobrescrita ( overriding ).

26.3.1.1 Polimorfismo Ad-hoc (PAH) de Sobrecarga
É o tipo de polimorfismo que funciona baseado na ideia de sobrecarga de métodos, ou seja, na utilização de um mesmo nome para dois ou mais métodos, mas definindo assinaturas diferentes (distinção estática, portanto, feita pelo programador) de modo que o compilador possa selecionar qual código gerar em tempo de compilação.

26.3.1.2 Polimorfismo Ad-hoc (PAH) de Coerção

Esse tipo de polimorfismo se baseia no sistema de conversão implícita de tipo suportado pela linguagem de programação. Portanto, funciona através do que se conhece como **sobrecarga de operadores** , ou seja, ocorre quando se converte um elemento de um tipo em outro mais apropriado.

No exemplo, o sistema de conversão implícita de tipos do Java permite que um inteiro seja convertido para *double* . De fato, via de regra, um tipo de grandeza menor (em bytes) sempre pode ser convertido em um tipo de grandeza maior.

# Sobrecarga: (sobrecarga de método) utiliza tipos para definir o método correto.

# Coerção: (sobrecarga de operador) utiliza a definição do método para escolher o tipo de conversão.

26.3.2.1 Polimorfismo Universal (PMU) Paramétrico

Considerado como “o polimorfismo verdadeiro”, define que um mesmo objeto pode ser utilizado como parâmetro em diferentes contextos. A distinção entre o objeto “correto” e o objeto passado como parâmetro ocorre por meio de um parâmetro discriminante explícito ou implícito. Logo, através de modelos comportamentais, associa um conjunto variável de tipos de objetos a um padrão determinado.

O polimorfismo paramétrico permite que se programe métodos genéricos retirando a referência a declarações de tipo de parâmetro até o momento da execução.

# Generics : na linguagem Java, esse tipo de polimorfismo recebe o nome de generics e foram implementados de forma similar aos templates do C++.

26.3.2.2 Polimorfismo Universal (PMU) de Sobrescrita

Também conhecido como polimorfismo de inclusão ou subtipagem , é o tipo de polimorfismo que se baseia na subtipagem e na herança. É o tipo de polimorfismo que permite a um objeto pertencer a várias classes simultaneamente, criando uma hierarquia de herança. Em uma subclasse, um objeto pode apresentar um comportamento modificado em relação à classe mãe. Assim, as instâncias das subclasses podem ser manipuladas pelos mesmos métodos que manipulam as instâncias da superclasse.

O polimorfismo permite se programar no geral em vez de programar no específico, pois habilita-nos a escrever programas que processam objetos que compartilham a mesma superclasse (direta ou indiretamente) como se todos fossem objetos da superclasse.

1 curtida

Pratique projetos, perda de tempo ficar se estendendo em definições.

Entendo que polimorfismo de inclusão/subtipagem e polimorfismo de sobreposição são a mesma coisa.

Eu nunca fui a fundo no polimorfismo. Só dominei o gist dele (esse que é chamado de universal): um objeto de um tipo assume outras formas, isto é, um outro tipo, no momento da chamada do método sobrescrito (isto é, em tempo de execução, por isso late binding). Assume o tipo da classe que foi instanciada, e portanto chama a versão do método que foi implementada por último. É o que o colega acima quis dizer mas falou o oposto, falou que o subtipo assume a forma do supertipo.

Polimorfismo paramétrico no Java é com Generics mesmo, está se referindo à possibilidade de impor restrições ao tipo do parâmetro da classe. Parâmetros da classe são o que está entre < > na declaração da classe genérica. Então quando você diz List< Tipo > ou List<? extends Tipo> está empregando polimorfismo paramétrico.

Tem também o polimorfismo de sobrecarga, que nem todo mundo considera polimorfismo, é a sobrecarga de funções/métodos, que é quando tem mais de uma função/método com mesmo nome mas lista de parâmetros diferente.

E esse que eu não sabia que era polimorfismo, o de coerção: um inteiro virar um long, por exemplo.

Tudo dentro do que você falou.