Na programação, Polimorfismo é um conceito de Programação Orientada a Objetos. Ele permite usar uma única interface com a entrada de diferentes tipos de dados, diferentes classes ou talvez para um número diferente de entradas.

Exemplo: Neste caso, a função len() é polimórfica, pois recebe uma string como entrada no primeiro caso e uma lista como entrada no segundo caso.

x = len('Geeks') 
print(x) 
y = len([1, 2, 3, 4]) 
print(y)

Resultado:

5
4

Em Python, o polimorfismo é uma maneira de fazer uma função aceitar objetos de classes diferentes se eles se comportarem de maneira semelhante.

Existem quatro maneiras de implementar o polimorfismo em Python:



1. Duck Typing : Duck Typing é um conceito que diz que o "tipo" do objeto é uma questão de preocupação apenas em tempo de execução e você não precisa mencionar explicitamente o tipo do objeto antes de realizar qualquer tipo de operação no esse objeto, ao contrário da tipagem normal em que a adequação de um objeto é determinada por seu tipo.

Em Python, temos o conceito de tipagem dinâmica, ou seja, podemos mencionar o tipo de variável / objeto posteriormente. A ideia é que você não precisa de um tipo para invocar um método existente em um objeto se um método estiver definido nele, você pode invocá-lo.

class Geeks1: 
  def code (self, ide): 
    ide.execute() 
      
class Geeks2: 
  def execute (self): 
    print("GeeksForGeeks is the best Platform for learning") 
      
ide = Geeks2() 
G1 = Geeks1() 
G1.code(ide)

Resultado:

GeeksForGeeks é a melhor plataforma de aprendizagem

2. Sobrecarga de método: Por padrão, Python não oferece suporte a sobrecarga de método, mas podemos consegui-la modificando seus métodos.

Dada uma única função sum(), o número de parâmetros pode ser especificado por você. Esse processo de chamar o mesmo método de maneiras diferentes é chamado de sobrecarga de método .

Conceito de sobrecarga de método 


class GFG: 
    def sum(self, a = None, b = None, c = None):          
        s = 0
        if a != None and b != None and c != None: 
            s = a + b + c 
        elif a != None and b != None: 
            s = a + b 
        else: 
            s = a 
        return s 
        
s = GFG() 
print(s.sum(1)) 
print(s.sum(3, 5)) 
print(s.sum(1, 2, 3))

Resultado:



1
8
6

3. Sobrecarga de operador : A sobrecarga de operador em Python é a capacidade de um único operador realizar mais de uma operação com base na classe (tipo) de operandos. Portanto, basicamente definir métodos para operadores é conhecido como sobrecarga de operador. Por exemplo: Para usar o operador + com objetos personalizados, você precisa definir um método chamado __add__.

 Sabemos que o operador + é usado para adicionar números e, ao mesmo tempo, concatenar strings. É possível porque o operador + está sobrecarregado por ambos classe int e classe str . Os operadores são, na verdade, métodos definidos nas respectivas classes. 

Portanto, se você quiser usar o operador + para adicionar dois objetos de alguma classe definida pelo usuário, terá que definir esse comportamento você mesmo e informar ao Python sobre isso.

class Student: 
    def __init__(self, m1, m2): 
        self.m1 = m1 
        self.m2 = m2 
  
S1 = Student (58, 60) 
S2 = Student (60, 58) 
S3 = S1 + S2

Resultado:

TypeError: tipo (s) de operando não suportado (s) para +: 'Aluno' e 'Aluno'

Portanto, podemos ver que o operador + não é compatível com uma classe definida pelo usuário. Mas podemos fazer o mesmo sobrecarregando o operador + para nossa classe.

class Student: 
    
    
    def __init__(self, m1, m2): 
        self.m1 = m1 
        self.m2 = m2 
  
    
    def __add__(self, other): 
        m1 = self.m1 + other.m1 
        m2 = self.m2 + other.m2 
        s3 = Student(m1, m2) 
        return s3 
  
s1 = Student(58, 59) 
s2 = Student(60, 65) 
s3 = s1 + s2 
print(s3.m1)

Resultado:

118

4. Substituição de método: Ao usar a substituição de método, uma classe pode “copiar” outra classe, evitando código duplicado e, ao mesmo tempo, aprimorar ou personalizar uma parte dele. A substituição de método é, portanto, uma parte do mecanismo de herança.

Em Python, a substituição de método ocorre simplesmente definindo a classe filha em um método com o mesmo nome de um método na classe pai.

class Programming: 
    
    
    DataStructures = True
    Algorithms = True
      
    
    def practice(self): 
        print("Practice makes a man perfect") 
      
    
    def consistency(self): 
        print("Hard work along with consistency can defeat Talent") 
          
class Python(Programming): 
      
    
    def consistency(self): 
        print("Hard work along with consistency can defeat Talent.") 
  
Py = Python() 
Py.consistency() 
Py.practice()

Resultado:

O trabalho árduo e a consistência podem derrotar o Talento.
A prática torna um homem perfeito