sexta-feira, 23 de março de 2007

POO - Polimorfismo

Olá a todos. Este é outro post falando das técnicas de programação orientada a objetos.

Polimorfismo é a técnica que permite implementar um método numa classe que tenha o comportamento diferente do método na sua classe ancestral. Podemos entender como um exemplo um objeto chamado Automóvel, que tem dois descendentes: Carro e Moto.

O Objeto Automóvel tem um método chamado ligar, que todo automóvel possui. Os objetos Carro e Moto também têm o método ligar, porém com implementações diferentes entre si.

Vamos fazer alguns códigos:

Delphi:

interface

type

  TAutomovel = class
    public
      procedure Ligar;
  end;


  TCarro = class(TAutomovel)
    public
      procedure Ligar; override;
  end;

  TMoto = class(TAutomovel)
    public
      procedure Ligar; override;
  end;

implementation

procedure TAutomovel.Ligar;
begin
  {implementação do método Ligar da classe TAutomovel}
end;


procedure TCarro.Ligar;
begin
  {a palavra chave inherited indica que este método vai incluir a 
   implementação do método do ancestral no ponto em que foi inserida}
  inherited;
  
  {implementação do método Ligar da classe TCarro}
end;


procedure TMoto.Ligar;
begin
  {a palavra chave inherited indica que este método vai incluir a
   implementação do método do ancestral no ponto em que foi inserida}
  inherited;
  
  {implementação do método Ligar da classe TMoto}
end;


Java:

class Automovel {
  pubic void ligar() {
    // implementação do método ligar da classe Automovel
  }
}

class Carro extends Automovel {
  public void ligar() {
    // o método super() chama a implementação do método da classe
    // ancestral no ponto em que foi iserido
    super();

   // implementação do método ligar da classe Carro
  }
}

class Moto extends Automovel {
  public void ligar() {
    // o método super() chama a implementação do método da classe
    // ancestral no ponto em que foi iserido
    super();

   // implementação do método ligar da classe Moto
  }
  
}


C#

class Automovel {
  public void ligar() {
    // implementação do método ligar da classe Automovel
  }
}

class Carro : Automovel {
  public override void ligar() {
    // a chamada a base. chama a implementação do método da classe
// ancestral no ponto em que foi iserido
base.ligar();

// implementação do método ligar da classe Carro
}
}

class Moto : Automovel {
public override void ligar() {
// a chamada a base. chama a implementação do método da classe
// ancestral no ponto em que foi iserido
base.ligar();

// implementação do método ligar da classe Moto
}
}


Outra forma de polimorfismo é quando a classe ancestral tem um método mas não faz nenhuma implementação, deixando-a por parte das suas classes descendentes. Este tipo de método é chamado abstrato. Neste caso a classe derivada é obrigada a fazer sua própria implementação do método.

Vou abrir um pequeno parêntesis para falar sobre 'abstratos' em POO.

Geralmente métodos e classes abstratas apenas repredentam a idéia e não a funcionalidade. Vamos a exemplos:

Classes abstratas não podem ser instanciadas.

O quê? Como assim? Por que ter classe se eu não posso instanciá-la?
Uma das principais vantagens de se usar classes abstratas é que nos permite introduzir comportamento comum aos descendentes.

Vamos a um exemplo prático: Figuras geométricas. O que é exatamente uma figura geométrica? Nós não temos uma resposta concreta porque figura geométrica é um objeto abstrato. Mas quanto a quadrado? Retângulo? Losango? Estes são figuras geométricas que podemos descrever claramente.

Todas as figuras geométricas têm um método chamado 'desenhar', mas as implementações são diferentes entre as figuras. É aí que entram a classe abstrata e o método abstrato.

Classes abstratas não podem ser instanciadas. Por um motivo bem simples: Porque são abstratas! Hehe... A classe só tem uma estrutura básica para servir de base para as suas classes descendentes.

Por exemplo, a classe FiguraGeometrica tem o método abstrato Desenhar, que aceita como argumentos as coordenadas de onde ele vai começar a ser desenhado (x e y). Todos os seus descendentes terão este método, mas cada um deles deve ter sua própria implementação.


Delphi

type
TFiguraGeometrica = class
public
procedure Desenhar(const x, y: Integer); virtual;
end;


TQuadrado = class(TFiguraGeometrica)
public
procedure Desenhar(const x, y: Integer); override;
end;

TLosango = class(TFiguraGeometrica)
public
procedure Desenhar(const x, y: Integer); override;
end;

...

procedure MontarFigura(Figura: TFiguraGeometrica; const x, y: Integer);
begin
Figura.Desenhar(x, y);
end;


Java

abstract class FiguraGeometrica {
abstract void desenhar(int x, int y);
}

class Quadrado extends FiguraGeometrica {
public void desenhar(int x, int y) {
// implementação do método desenhar do objeto Quadrado
}
}

class Losango extends FiguraGeometrica {
public void desenhar(int x, int y) {
// implementação do método desenhar do objeto Losango
}
}


...

void montarFigura(FiguraGeometrica figura, int x, int y) {
figura.desenhar(x, y);
}


C#

abstract class FiguraGeometrica {
public abstract void desenhar(int x, int y);
}


class Quadrado : FiguraGeometrica {
public override void desenhar(int x, int y) {
// implementação do método desenhar do objeto Quadrado
}
}

class Losano : FiguraGeometrica {
public override void desenhar(int x, int y) {
// implementação do método desenhar do objeto Losango
}
}


...

public void montarFigura(FiguraGeometrica figura, int x, int y) {
figura.desenhar(x, y);
}


Mas Felipeeee... que efeito prático isso vai ter na aplicação?

Desta forma nós evitamos redundância no nosso código, 'if' que não precisamos... Quando executamos o método MontarFigura nós passamos qualquer objeto derivado da classe FiguraGeometrica que, pelo fato dela ser abstrata (virtual em delphi) ela vai executar o método da classe derivada correspondente. Maneiro, né...

Esse post acabou sendo mais longo que eu esperava, mas espero que o conteúdo postado tenha sido bem absorvido. Abraços.

Um comentário:

  1. Guri vlw, amanhã eu tenho Avaliação de POO na facul, e vc me ajudou bastante a entender Polimorfismo!

    muito obrigada!

    ResponderExcluir

 
BlogBlogs.Com.Br