TCollection e Generics no Free Pascal - Uma breve visão sobre lista de objetos com o Lazarus

O Free Pascal pode não ser tão poderoso quanto o C++, mas em seus termos, está bem madura e tem evoluído - e para aplicações simples pode representar um excelente custo benefício, numa prova de que com ele é possível conciliar recursos poderosos com simplicidade.

[ Hits: 29.372 ]

Por: Perfil removido em 05/05/2010


Coleções (TCollection)



A classe TCollection já é antiga (se eu não me engano surgiu no Delphi 3, em meados do ano de 1997) e o Lazarus (lançado em 1999) já trouxe este recurso de início, valendo-se do que o compilador Free Pascal (lançado em 1993) já oferecia.

O exemplo é extremamente simples e não chega a abordar de maneira tão ampla tudo o que o tema contempla, mas serve como base pra que você possa estender as suas possibilidades. Basicamente, vamos fazer uma agenda telefônica com código, nome e número, apenas para exibição, sem gravação em banco de dados nem nada, só mesmo pra exemplificar como usar listas de objetos pra guardar dados em memória durante a execução de um aplicativo.

A coleção em si na verdade é que é o nosso objeto nesse caso. Ela é um objeto que contém itens que armazenam propriedades que podem ser de tipos primitivos (como Integer, String) ou que sejam objetos, ou seja, os objetos que listamos na verdade são apenas uma das várias propriedades que os itens da coleção podem ter, então não é direta e puramente uma lista destes objetos. Esses próprios itens por sua vez são uma propriedade do objeto TCollection.

A declaração da nossa coleção simplesmente reproduz o que a classe pai faz, implementaremos nela os métodos básicos para adicionar, remover e selecionar itens seguindo a TCollection, no máximo temos um método customizado nosso pra deletar itens pelo código interno atribuído por nós mesmos.

{ TAgendaColecao }
TAgendaColecao = class(TCollection)
private
   function GetItem(Index: Integer): TAgendaColecaoItem;
   procedure SetItem(Index: Integer; const Value: TAgendaColecaoItem);
public
   constructor Create();
   destructor Destroy(); override;
   function Add: TAgendaColecaoItem; overload;
   procedure Add(const Nome: String; const Telefone: String);
   procedure DeleteByCodigo(Codigo: Integer); { Método customizado }
   property Items[Index: Integer]: TAgendaColecaoItem read GetItem write SetItem;
end;

A implementação dos métodos e funções GetItem, SetItem, Create e Destroy da nossa TAgendaColecao apenas herdam a implementação do pai instanciando o nosso TAgendaColecaoItem, que é declarado assim...

{ TAgendaColecaoItem }
TAgendaColecaoItem = class(TCollectionItem)
private
   FCodigo: Integer;
   FNome: String;
   FTelefone: String;
public
   property Codigo: Integer read FCodigo;
   property Nome: String read FNome Write FNome;
   property Telefone: String read FTelefone write FTelefone;
end;

Nossos itens da coleção são simples, então precisam ser apenas declarados como classe do tipo TCollectionItem, nem precisa implementar nada. Mas, voltando às implementações dos métodos e funções básicos da nossa coleção eles ficam assim...

function TAgendaColecao.GetItem(Index: Integer): TAgendaColecaoItem;
begin
  Result := TAgendaColecaoItem(inherited Items[Index]);
end;

procedure TAgendaColecao.SetItem(Index: Integer; const Value: TAgendaColecaoItem);
begin
  inherited Items[Index] := Value;
end;

constructor TAgendaColecao.Create();
begin
  inherited Create(TAgendaColecaoItem);
end;

destructor TAgendaColecao.Destroy();
begin
  inherited Destroy();
end;

function TAgendaColecao.Add: TAgendaColecaoItem;
begin
  Result := TAgendaColecaoItem(inherited Add());
end;

O que muda é a procedure Add (note que temos uma function e uma procedure Add que trabalham em conjunto, a function cria um novo item e a procedure é quem chamamos no nosso programa pra atribuir valores às propriedades do item). E, é claro, também precisamos implementar o nosso método customizado, que localiza o índice do item pelo código interno que demos a ele e o deleta.

Veja:

procedure TAgendaColecao.Add(const Nome: String;
  const Telefone: String);
var
  I, Codigo: Integer;
  Item: TAgendaColecaoItem;
begin
  //Pega último código registrado e incrementa
  //pra obter o código interno pro novo item
  if Count > 0 then
  begin
    for I := 0 to Count - 1 do
      Codigo := Items[I].Codigo + 1;
  end
  else
    Codigo := 1;

  //Adiciona e valoriza
  Item := Add();
  Item.FCodigo := Codigo;
  Item.FNome := Nome;
  Item.FTelefone := Telefone;
end;

procedure TAgendaColecao.DeleteByCodigo(Codigo: Integer);
var
  I: Integer;
begin
  for I := 0 to Count - 1 do
    if Items[I].Codigo = Codigo then
    begin
      Delete(I);
      Break;
    end;
end;

Feito isso, no nosso programa declaramos, por exemplo, Agenda como do tipo TAgendaColecao e para inserir usamos:

Agenda.Add('Pedro Araújo', '(00)0000-0000');

E pra deletar usamos o nosso método customizado:

Agenda.DeleteByCodigo(10);

Pra exibir, supondo que usemos uma ListView, listamos item por item da coleção num for e inserirmos nela...

for I := 0 to Agenda.Count - 1 do
begin
   Item := ListView1.Items.Add();
   Item.Caption := IntToStr(Agenda.Items[I].Codigo);
   Item.SubItems.Add(Agenda.Items[I].Nome);
   Item.SubItems.Add(Agenda.Items[I].Telefone);
end;

Página anterior     Próxima página

Páginas do artigo
   1. Apresentação
   2. Coleções (TCollection)
   3. Usando generics
   4. Interface e código completo do exemplo
Outros artigos deste autor

Tutorial de instalação do H3270 (sources) com SSL no RHEL5 (s390x)

Escreva para o VOL - Contribua você também!

Resumo LPI 102: Tópico 107 - Tarefas Administrativas

Qmail + Patches + Performance Tuning, the Debian AMD64 way

Distribuições Linux no Samsung Chromebook ARM (XE303C12)

Leitura recomendada

Cross-compile Lazarus: Gerando executáveis Win32 estando no Linux

Como fazer seu programa Kylix chamar uma aplicação externa

Aprendendo a modelar forms no Kylix

Capturando seu desktop com uma aplicação feita em kylix

Criando uma aplicação que mostra os processos em execução

  
Comentários
[1] Comentário enviado por barao em 06/05/2010 - 11:23h

Bom artigo Pedro, tambem gosto muito da linguagem pascal e do c ,mais com as facilidades que o Lazaros vem incroporando a cada dia ele fica melhor.
Meu blog www.blig.ig.com.br/mauriciobaron

[2] Comentário enviado por andrezc em 07/05/2010 - 20:02h

Parabéns pelo artigo! Mas serei sincero com você, odeio Pascal, rs, isso é mais pq eu não gostei da sintaze, foi odio a primeira vista, em um curso que eu fiz.

Um abraço, parabéns pelo artigo.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts