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.