10 de fev. de 2010

Sobrecarga e Python

Boa noite pessoal!!!
Sobrecarga é uma palavra/conceito muito usado por programadores de linguagens OO. Existem dois tipos de sobrecarga, de métodos e operadores, e cada linguagem tem seu suporte. Java, por exemplo, suporta apenas sobrecarga de método:

private int soma(int x, int y){
 return x+y;
}

private int soma(float x, float y){
 return x+y;
}

O C# suporta subrecarga de métodos e operadores. A sobrecarga de métodos do C# é igual a do Java, e já foi mostrada acima. Sobrecarga de operadores consiste, falando de maneira grossa, em dar um novo meio de interpretação a um operador matemático. Veja o exemplo:

public class Cliente{
 public int x = 0;
 public int y = 0;
 public Cliente() : this(0,0){}

 public Cliente(int x, int y){
  this.x = x;
  this.y = y;
 }

 public static Cliente operator+(Cliente a, Cliente b){
  return new Cliente(a.x*a.y,b.x*b.y); //Fazer isso é perigo, pode causar confusões
 }
}

OK, já falei de Java e de C# mas, e o Python? Pois é meu amigo, o Python essa histórinha é um pouco diferente, alias não existe sobrecarga no Python, isso mesmo não existe ^^. "Pow, mas uma vez eu vi num site dizendo que: era só eu implementar o método __add__ na minha classe. Ai, quando eu fizesse x + y, ele ia fazer o que eu implementei". Bom, realmente, isso não está errado porém, isso não é sobrecarga e por motivos simples. O Python é completamente OO, então tudo no Python é a execução de métodos de objetos. Na expressão x + y está ocorrendo a execução do método __add__ sim, da seguinte forma:

type(x).__add__(y)

Logo, quando você cria um método __add__ na sua classe, O Python executa o método que foi definido nele. Vou exemplificar, do mesmo modo que foi exemplificado a mim quando estava estudando:

class A:
    def abc(self):
        pass

class B(A):
    pass 

b = B()

Como podem ver, B não tem o método "abc" definido em seu escopo, ele está em A. Então, quando fazemos uma chamada ao método abc em B, o interpretador primeiramente vai verificar se b tem o método abc, sendo a resposta negativa, o próximo passo é verificar B que, como foi dito anteriormente, não tem o método. Por último ele verifica A, que é o possuidor do método abc, e encontra o método e em seguida o executa. Caso você defina um método abc em B esse mesmo processo é executado, porém quando o interpretador verificar se B tem o atributo abc, ele vai achar e executar, sem tocar no abc que está em A. O metodo de A não foi sobrecarregado, nem sobrescrito, ele continua lá, como sempre foi. Meio complicado mesmo, vou tentar resumir.

Não há sobrecarga de operadores no Python pois, a chamada x + y na realidade é uma outra forma de se fazer "type(x).__add__(y)" então, quando você implementa o metodo __add__ na sua classe, o Python apenas deixa de chamar o __add__ normal e passa a chamar o da sua classe. Por isso há uma falsa impressão de sobrecarga.

Bom pessoal, isso é a pontinha do iceberg, isso gera um papo longo, que vou explorar mais pra frente(quando eu estiver entendendo 100%, rsrs). Mas podemos dizer que: "Sobrecarga no Python é apenas um engano de conceitos".

Espero que estejam gostando de tudo. Estou sempre à disposição de vocês para dúvidas/sugestões/críticas ok?

Abraços!!!

2 comentários:

  1. opa! ta ficando bacana hein Felipe!

    Se quiser entender certinho como funciona, le o tópico de herança múltipla do Learning Python (Aprendendo Python versão português) la mostra exatamente o que acontece. Resumindo Python faz uma pesquisa na árvore de heranças, sempre de baixo para cima e da esquerda para a direita para procurar o método.

    Continue com a excelente inciativa!

    Abraços!
    Rodrigo

    ResponderExcluir
  2. Fala Rodrigão!!!
    Esse assunto é muito grande. Para um entendimento afundo, vários assuntos devem ser estudados. Mas com certeza herança múltipla será o tema do próximo post. Agredeço sua participação, espero mais sugestões de todos!
    E muito obrigado pelo elogio. Fico muito feliz.

    Abraços

    ResponderExcluir