You are on page 1of 2

:: Active Delphi Página 1

Classes e Objetos
Data: Thursday, December 19 @ 20:04:48
Tópico Administrador

Criando uma classe simples


Uma classe, como vimos, define a estrutura de vários objetos semelhantes. Cada objeto é uma instância da classe, que tem essa mesma estrutura. Por exemplo, se quisermos representar um ponto na tela, podemos
criar uma classe contendo as coordenadas x e y:
type
TPonto = class
x, y: integer;
end;

Vamos usar essa classe dentro de um projeto para manter uma lista de pontos e desenhar (ligar esses pontos) quando for necessário.
Exemplo: desenho de pontos
Crie um novo projeto e coloque dois botões no formulário, com as propriedades:

1º ponto: Caption: "Ligar pontos" e Name: btnLigar


2º ponto: Caption: "Limpar lista" e Name: btnLimpar

Na unidade do formulário, declare a classe 'TPonto', logo após a implementation, da forma como foi colocado acima. Acrescente também as seguintes declarações de variáveis:

var
Lista: array of TPonto;
N: integer;
A variável 'Lista' é um vetor de pontos, que seu tamanho será criado em tempo de execução.
Cada elemento desse vetor é uma referência a um objeto da classe TPonto. A variável 'N' será usada para controlar quantos elementos estão sendo usados em 'Lista'.
Como iremos criar o tamanho do vetor em tempo de execução , então no evento OnCreate do fomulário acrescente o código abaixo:
procedure TForm1.FormCreate(Sender: TObject);
begin
setlength(lista, 30)
end;
Com o comando setlength definimos que o tamanho do vetor será de 30 posições.
No evento OnMouseDown do formulário, vamos pegar as coordenadas do ponto que foi clicado e criar um objeto TPonto para guardá-las:
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var p: TPonto;
begin
p := TPonto.Create; //cria o objeto
p.x := X;
p.y := Y;
Lista[N] := p; //guarda na lista
N := N + 1;
Canvas.Pixels[X,Y] := clBlue;//pinta um ponto azul
end;
Ao clicar no botão "Ligar pontos", vamos percorrer a lista de pontos e desenhar linhas entre eles:
procedure TForm1.btnLigarClick(Sender: TObject); var k: integer; p: TPonto;
begin
if N = 0 then
exit; // nada para ligar
//definir a pos. de desenho no primeiro ponto
Canvas.MoveTo(Lista[0].x, Lista[0].y);
for k := 1 to N-1 do
begin
p := Lista[k];
Canvas.LineTo(p.x, p.y);//liga o anterior com p
end;
end;

A última linha antes do end poderia ser escrita também:


Canvas.LineTo(Lista[k].x, Lista[k].y);

Liberar memória
Agora falta limpar a memória usada pelos pontos quando o usuário clica no botão "Limpar lista". Para isso, vamos percorrer o vetor de pontos e chamar o método Free em cada um deles:
procedure TForm1.btnLimparClick(Sender: TObject);
var k: integer;
begin
for k := 0 to N-1 do
begin
Lista[k].Free; //destrói o objeto
Lista[k] := nil; //indica que não tem mais ref.
end;
N := 0;
end;
Note que quando você fizer 'Lista[k].Free', o elemento na posição 'k' do vetor passa a conter uma referência inválida a um objeto que já foi liberado. Por segurança, colocamos o valor nil nesse elemento.
Salve os arquivos desse projeto como PONTOS .PAS e PONTOSP.DPR.
Listas de objetos
No exemplo anterior (PONTOSP.DPR), usamos um vetor para armazenar os objetos, de acordo com o comando SetLength definimos que seu tamanho será 30 , mas este tamanho pode ser aumentado de
acordo com a necessidade.Mas é necessário usar a variável N para saber quantos pontos foram adicionados. Em vez de usar vetor, iremos utilizar a classe TList, para ter uma idéia do seu funcionamento.
Um objeto TList funciona como um vetor dinâmico. Quando você acrescenta um objeto a ele, ele aumenta de tamanho. Você pode também retirar objetos dinamicamente. A propriedade Count diz a
quantidade de objetos existentes dentro do TList. Inicialmente ela será 0 (lista vazia).
Vamos alterar o projeto anterior (PONTOSP.DPR) para usar um TList em vez de um vetor.
Exemplo: usando um objeto TList
Na unidade principal do projeto (PONTOS.PAS), logo após a palavra implementation, existem algumas declarações de variáveis. Apague as declarações das variáveis 'Lista' e 'N'. Troque pelo seguinte:
var
Lista: TList;

O objeto TList já tem a propriedade Count, por isso não é preciso uma variável separada só para guardar a contagem de elementos.
Essa declaração de variável não cria um objeto TList. Ela só diz que a variável 'Lista' está apta a referenciar um objeto TList. Altere o procedimento de evento OnCreate do formulário, para inicializar essa
variável, criando um objeto TList:
procedure TForm1.FormCreate(Sender: TObject);
begin
Lista := TList.Create;
end;
No evento OnMouseDown do formulário, faça as seguintes alterações:
begin
p := TPonto.Create; //cria o objeto
p.x := X;
p.y := Y;
Lista.Add(p); //guarda na lista
Canvas.Pixels[X,Y] := clBlue;//pinta um ponto azul
end;
O método Add adiciona um objeto à lista e aumenta o valor de Lista.Count. Agora você deve alterar também o procedimento do 'btnLigar':

http://www.activedelphi.com.br/print.php?sid=18 8/19/2010 3:17:10 PM


:: Active Delphi Página 2

begin
if Lista.Count = 0 then
exit;
p := TPonto(lista.items[0]);
Canvas.MoveTo(p.x, p.y);
for k := 1 to Lista.Count - 1 do
begin
p := TPonto(Lista.Items[k]);
Canvas.LineTo(p.x, p.y);
end;
end;
Note que 'Lista.Count' agora faz o papel de N. A propriedade Items é um vetor que retorna um item guardado na lista, dado a posição. Mas essa propriedade retorna um item do tipo pointer (ponteiro), que
pode ser várias coisas em Object Pascal: uma referência de objeto, um PChar, ou outros tipos de ponteiro.
Resumindo, 'Lista', um objeto TList, não sabe o tipo de objeto que foi guardado nele e nem se importa com isso. Mas quando você vai pegar um objeto de volta, deve informar o seu tipo, o que é feito com a
sintaxe TPonto(Lista.Items[k]) ou, em geral, NomeDaClasse(valor). Com isso, você está interpretando valor como sendo uma referência de objeto daquela classe.
Agora falta liberar a memória dos objetos TPonto e, além disso, retirá-los do TList. Note que são duas ações separadas: se você executa Free para um objeto, você vai destruir esse objeto, mas pode ser que
na lista ainda haja uma referência para ele. Abra o procedimento de evento 'btnLimparClick':
var k: integer;
p: TPonto;
begin
for k := 0 to Lista.Count - 1 do
begin
p := TPonto(Lista[k]);
p.Free; //destrói o objeto
end;
// limpar a lista
Lista.Clear;
end;
Para limpar toda a lista, usamos o método Clear. Se usássemos apenas o Clear, o objeto TList ficaria vazio, mas os objetos que ele referenciava continuariam existindo e ocupando memória.
Salve o projeto novamente.
Nota: a propriedade Items pode ser omitida, por exemplo:p := TPonto(Lista[k]);
Outros métodos do TList
Além dos métodos e propriedade que utilizamos, a classe TList tem alguns outros que podem ser úteis, como:
Insert(pos,novoItem)
- Insere um item no meio, na posição 'pos' e desloca os outros para frente. (Diferente de Add, que acrescenta ao final).
Delete(pos)
- Remove um item, dada a posição
Remove(item)
- Remove um item, dada uma referência a ele.
IndexOf(item)
- Função que Procura um item na lista e retorna a posição onde ele está, ou -1 se não encontrou
Exchange(posPrimeiro, posSegundo)
- Troca os dois itens de lugar: o que está em 'posPrimeiro' e o que está em 'posSegundo'
Sort(NomeFuncao)
- Ordena a lista. O parâmetro é o nome de uma função de comparação que será chamada durante a ordenação. Essa função deve ser declarada como:
function NomeFuncao(Item1,Item2: Pointer): Integer;
A função deve retornar um valor negativo se Item1 < Item2, um valor positivo se Item1 > Item2 e zero se Item1 = Item2.

Autor : Celso Rodrigues


Contato : celso@finta.com.br

Digitado por :: Active Delphi


http://www.activedelphi.com.br/

A URL para esta notícia é:


http://www.activedelphi.com.br/modules.php?op=modload&name=News&file=article&sid=18

http://www.activedelphi.com.br/print.php?sid=18 8/19/2010 3:17:10 PM