Orientação a Objetos para Iniciantes - Polimorfismo

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (2)  (1)

Acredito que uma boa compreensão deste item seja de grande importância para os estudos da POO. Então resolvi fazer um artigo apenas sobre este conceito.

Acredito que uma boa compreensão deste item seja de grande importância para os estudos da POO. Pensando nisso, comecei a pesquisar na internet uma forma simples de passar este conceito. Acabei encontrando um pequeno programa que desenha em um componente TImage três figuras diferentes, através de uma classe pré-definida. Fiz algumas alterações no código fonte deste programa para que a didática e o entendimento fossem facilitados. Bom, iremos criar neste exemplo uma classe chamada TClassFigura, e dela criaremos outras 2 classes descendentes. Cada uma destas classes será responsável pela criação de uma figura diferente.
Abra o seu Delphi, e crie uma nova Unit (File -> New -> Unit). Está unit será criada com o nome Unit1.

Verifique agora como ficará a nossa unit após a criação da primeira classe.

unit Unit1;

interface

uses
extCtrls, graphics, classes;

type
TClassFigura = class
private
MinhaImagem: TImage;
public
property Imagem: TImage read MinhaImagem write MinhaImagem;
procedure Criar; virtual;
end;

implementation

end.


Informações importantes:

TClassFigura = class
Sempre que declaramos uma classe sem especificar de quem ela é descendente, subentende-se que ela possui como classe-pai TObject, que é a classe-pai de toda e qualquer classe criada. Sua declaração é opcional, sendo assim poderíamos declarar essa classe também como: TClassFigura = class(TObject) que estaria correto da mesma forma, porém como víamos a cima, isso não é necessário.

A frente da procedure Criar temos a palavra virtual, mas o que ela significa?

Sempre que utilizamos a clausula “virtual” estamos sinalizando que nas classe derivadas este método poderá ser reescrito. Para isso basta declarar no método da classe filha a clausula “override”.
Sempre que utilizamos a clausula “override” estamos reescrevendo um método da classe pai.


Bom, com esses conceitos descritos vamos então implementar o código da classe TClassFigura. A implementação ficará da seguinte forma:

implementation

procedure TClassFigura.Criar;
begin
MinhaImagem.Canvas.Brush.Color := clYellow;
MinhaImagem.Canvas.Brush.Style := bsSolid;
MinhaImagem.Canvas.Pen.Color := clRed;
MinhaImagem.Canvas.Pen.Width := 3;
MinhaImagem.Canvas.Polygon([Point(10, MinhaImagem.Height -10), Point(trunc(MinhaImagem.Width / 2.0), 0 + 10),Point(MinhaImagem.Width - 10, MinhaImagem.Height -10)]);
MinhaImagem.Canvas.FloodFill(Trunc(MinhaImagem.Width / 2.0), Trunc(MinhaImagem.Height / 2.0), clRed, fsBorder);
end;

Quando a classe pai (TClassFigura) for acionada, ela irá desenhar um triângulo como figura padrão.

Volte no inicio da Unit, onde declaramos a nossa classe pai, e vamos agora criar duas novas classes que serão descendentes de TClassFigura. O estopo da nossa Unit ficará assim:

unit Unit1;

interface

uses
extCtrls, graphics, classes;

type
TClassFigura = class
private
MinhaImagem: TImage;
public
property Imagem: TImage read MinhaImagem write MinhaImagem;
procedure Desenhar; virtual;
end;

TClassQuadrado = class(TClassFigura)
public
procedure Criar; override;
end;

TClassCirculo = class(TClassFigura)
public
procedure Criar; override;
end;

implementation

Lembra quando eu expliquei a diferença entre as clausulas virtual e override? Agora acho que o conceito começará a fazer mais sentido...
Na classe pai quando acionada, desenhamos na tela um triângulo. Nas classes filhas TClassCirculo e TClassQuadrado a procedure criar será sobrescrita e irá desenhar os desenhos que iremos definir quando implementarmos a procedure criar das mesmas.

Vamos criar as classes filhas...

unit Unit1;

interface

uses
extCtrls, graphics, classes;

type
TClassFigura = class
private
MinhaImagem: TImage;
public
property Imagem: TImage read MinhaImagem write MinhaImagem;
procedure Desenhar; virtual;
end;

TClassQuadrado = class(TClassFigura)
public
procedure Criar; override;
end;

TClassCirculo = class(TClassFigura)
public
procedure Criar; override;
end;

Com a classe TClassCirculo será desenhado na tela um Circulo e com a classe TClassQuadrado será desenhado um quadrado na tela. Vamos implementar agora o metodo criar das classes filhas. Nossa Unit então ficarão do seguinte modo.

unit Unit1;

interface

uses
extCtrls, graphics, classes;

type
TClassFigura = class
private
MinhaImagem: TImage;
public
property Imagem: TImage read MinhaImagem write MinhaImagem;
procedure Desenhar; virtual;
end;

TClassQuadrado = class(TClassFigura)
public
procedure Criar; override;
end;

TClassCirculo = class(TClassFigura)
public
procedure Criar; override;
end;


procedure TClassFigura.Criar;
begin
MinhaImagem.Canvas.Brush.Color := clYellow;
MinhaImagem.Canvas.Brush.Style := bsSolid;
MinhaImagem.Canvas.Pen.Color := clRed;
MinhaImagem.Canvas.Pen.Width := 3;
MinhaImagem.Canvas.Polygon([Point(10, MinhaImagem.Height -10), Point(trunc(MinhaImagem.Width / 2.0), 0 + 10),Point(MinhaImagem.Width - 10, MinhaImagem.Height -10)]);
MinhaImagem.Canvas.FloodFill(Trunc(MinhaImagem.Width / 2.0), Trunc(MinhaImagem.Height / 2.0), clRed, fsBorder);
end;

procedure TClassQuadrado.Criar;
begin
MinhaImagem.Canvas.Brush.Color :=clGreen;
MinhaImagem.Canvas.Brush.Style := bsSolid;
MinhaImagem.Canvas.Pen.Color := clRed;
MinhaImagem.Canvas.Pen.Width := 3;
MinhaImagem.Canvas.Rectangle(10, 10, MinhaImagem.Width - 10, MinhaImagem.Height - 10);
end;

procedure TClassCirculo.Criar;
begin
MinhaImagem.Canvas.Brush.Color :=clBlue;
MinhaImagem.Canvas.Brush.Style := bsSolid;
MinhaImagem.Canvas.Pen.Color := clRed;
MinhaImagem.Canvas.Pen.Width := 3;
MinhaImagem.Canvas.Ellipse(10,10, MinhaImagem.Width - 10, MinhaImagem.Height - 10);
end;

end.

Eu criei uma pasta chamada “Classes” no diretório: “C:\Arquivos de programas\Borland\Delphi7” dessa forma eu centralizo em um único local todas as unit’s que eu codifiquei. Essa é uma dica para que você não se perca e saiba exatamente onde está aquela classe que você fez e precisa utilizar agora...

Nesta pasta salve sua unit com o nome UFiguras.

(Você pode salvar sua unit no diretório que preferir, está foi apenas uma dica).

No Delphi clique em: “Tools -> Enviroment Options -> aba Library.
Em Library Path clique nas reticências ao lado da caixa de texto e localize o diretório onde você salvou a unit.

Pronto, a unit com as classes está pronta para ser usada em qualquer um dos seus projetos.
Fácil, né?

Vamos agora criar o aplicativo que manipula as classes criadas anteriormente.
Crie um novo aplicarivo no Delphi (File -> New -> Application).

No Form1 da sua aplicação. Coloque dois componentes. Um TImage (encontrado na paleta Additional) e um TButton (localizado na paleta Standard).


Altere as propriedades dos componentes conforme descrito abaixo:
Form1:
Caption: Polimorfismo na Prática
Name: FrmPolimorfismo
Height: 461
Widht: 580

TImage:
Height: 409
Left: 8
Top: 8
Widht: 473
Name: imgFigura

TButton:
Caption: Desenhar
Top: 112
Left: 488
Heght: 25
Widht: 75
Name: btnDesenhar

Na seção uses declare as unit’s “UFiguras” e “Math”, ficará assim:

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, ExtCtrls, Unit2, Math;

Agora declare uma propriedade privada chamada Desenho. A declaração ficará assim:

type
TFrmPolimorfismo = class(TForm)
ImgFigura: TImage;
btnDesenhar: TBitBtn;
procedure btnDesenharClick(Sender: TObject);
private
{ Private declarations }
Desenho: TClassFigura;
public
{ Public declarations }
end;

Agora dê um duplo clique no botão e inclua o seguinte código:

procedure TFrmPolimorfismo.btnDesenharClick(Sender: TObject);
var j: Integer;
begin
J := RandomRange(1,4);
Randomize;
if j = 1 then
begin
Desenho := TClassQuadrado.Create;
Desenho.Imagem := imgFigura;
Desenho.Criar;
Desenho.Free;
end else
if j = 2 then
begin
Desenho := TClassCirculo.Create;
Desenho.Imagem := imgFigura;
Desenho.Criar;
Desenho.Free;
end else
if j = 3 then
begin
Desenho := TClassFigura.Create;
Desenho.Imagem := imgFigura;
Desenho.Criar;
Desenho.Free;
end;
end;

Agora execute o programa e clique diversas vezes no botão Desenhar e veja como o programa se comporta.
Duvidas estou a disposição no e-mail flavia@flavianeves.com.br
No próximo artigo falarei um pouco sobre encapsulamento. Outro item muito importante da POO.
Obs: Não citei o nome do autor do exemplo que citei na primeira parte deste artigo por não ter encontrado referencias sobre o mesmo.

Clique Aqui para ler o próximo artigo sobre Orientação a Objetos para Iniciantes, explicando sobre o Encapsulamento utilizado aqui.

Espero que estejam gostando dos artigos.

Flávia Neves dos Santos.
 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Receba nossas novidades
Ficou com alguma dúvida?