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;