Criando Classes e Métodos Genéricos em Delphi

Classes e Métodos Genéricos em Delphi
Generics

Introdução

Delphi é uma linguagem de programação orientada a objetos amplamente utilizada para o desenvolvimento de aplicativos robustos e escaláveis. Uma das funcionalidades que torna o Delphi tão poderoso é a capacidade de criar Generics. Generics permitem que você crie classes e métodos reutilizáveis que podem trabalhar com qualquer tipo de dado, promovendo flexibilidade e reduzindo a duplicação de código.

Este artigo irá explicar como criar classes e métodos genéricos em Delphi, abordando exemplos práticos de implementação e detalhando como definir e instanciar essas classes genéricas.

O que são Generics?

Generics são tipos parametrizados que permitem que você crie estruturas de dados ou algoritmos que podem operar sobre qualquer tipo de dado, sem comprometer a segurança do tipo. Isso é muito útil quando você deseja reutilizar o mesmo código com diferentes tipos de dados. Ao invés de criar várias versões da mesma classe para diferentes tipos de dados, você pode definir uma única classe genérica que funciona com todos os tipos.

Um exemplo comum de uso de Generics é em coleções como listas, onde você pode criar uma lista de inteiros, strings, ou até mesmo de objetos complexos.

Exemplo Prático de Implementação de Classes Genéricas

Vamos começar com um exemplo básico de uma classe genérica em Delphi que simula o comportamento de uma lista genérica. Essa lista pode armazenar qualquer tipo de dado, como inteiros, strings, ou objetos.

Nesse exemplo iremos precisar de dois botões(TButton) e duas caixas de texto grande (TMemo).

type
  TListaGenerica<T> = class
  private
    FItems: array of T;
  public
    procedure Add(Item: T);
    function Get(Index: Integer): T;
    function Count: Integer;
  end;

procedure TListaGenerica<T>.Add(Item: T);
begin
  SetLength(FItems, Length(FItems) + 1);
  FItems[High(FItems)] := Item;
end;

function TListaGenerica<T>.Get(Index: Integer): T;
begin
  Result := FItems[Index];
end;

function TListaGenerica<T>.Count: Integer;
begin
  Result := Length(FItems);
end;

Neste exemplo, TListaGenerica<T> é uma classe genérica. O parâmetro <T> permite que a classe aceite qualquer tipo de dado, que será definido no momento da instanciação da classe. Isso significa que podemos criar uma lista de inteiros, strings ou qualquer outro tipo de dado sem duplicar código.

Instanciando Classes Genéricas

A seguir, veja como instanciar a classe genérica para diferentes tipos de dados:

procedure TForm1.Button1Click(Sender: TObject);
var
  ListaDeInteiros: TListaGenerica<Integer>;
  i: Integer;

begin

  ListaDeInteiros := TListaGenerica<Integer>.Create; //Instancia a classe TListaGenerica utilizando o tipo inteiro
  try
    ListaDeInteiros.Add(42);  //adiciona itens do tipo inteiro na lista
    ListaDeInteiros.Add(100);

    //Exibe os itens no memo1
    Memo1.Clear;
    for i := 0 to ListaDeInteiros.Count-1 do
      Memo1.Lines.Add(ListaDeInteiros.Get(i).ToString);

  finally
    ListaDeInteiros.Free; //Libera a ListaDeInteiros da memória
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  ListaDeStrings: TListaGenerica<String>;
  i: Integer;
begin

  ListaDeStrings := TListaGenerica<String>.Create;   //Instancia a classe TListaGenerica utilizando o tipo string
  try
    ListaDeStrings.Add('Blog'); //adiciona itens do tipo string na lista
    ListaDeStrings.Add('codedelphi');

    //Exibe os itens no memo1
    Memo2.Clear;
    for i := 0 to ListaDeStrings.Count-1 do
      Memo2.Lines.Add(ListaDeStrings.Get(i));

  finally
    ListaDeStrings.Free; //Libera a ListaDeStrings da memória
  end;

end;

Aqui, utilizamos a classe TListaGenerica<T> para criar uma lista de inteiros e uma lista de strings. O código é altamente reutilizável e flexível, permitindo que você adicione qualquer tipo de dado sem alterar a lógica da classe.

Veja abaixo a ilustração do projeto:

Ilustração do projeto.

Código fonte do exemplo

Você pode fazer o download do exemplo do projeto através do repositório do github:

https://github.com/Gisele-de-Melo/Classe_Generics

Métodos Genéricos

Assim como as classes, os métodos também podem ser genéricos. Isso permite que você crie métodos que operam em qualquer tipo de dado, sem especificar o tipo de dado no momento da definição do método.

Nesse exemplo iremos precisar de dois botões(TButton) e duas caixas de texto grande (TMemo).

A seguir, veja um exemplo de um método genérico que troca o valor de duas variáveis:

procedure TForm1.Trocar<T>(var A, B: T);
var
  Temp: T;
begin
  //troca o conteúdo do parâmetro A para o B e do B para o A
  Temp := A;
  A := B;
  B := Temp;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  X, Y: Integer;

begin
  X := 10;
  Y := 20;
  Memo1.Clear;
  Memo1.Lines.Add('Iniciando com');
  Memo1.Lines.Add('X = '+IntToStr(X));
  Memo1.Lines.Add('Y = '+IntToStr(Y));

  Memo1.Lines.Add('Trocando para');
  Trocar<Integer>(X, Y);
  Memo1.Lines.Add('X = '+ IntToStr(X));
  Memo1.Lines.Add('Y = '+ IntToStr(Y)); // Saída: X = 20, Y = 10

end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Nome1, Nome2: String;

begin

  Nome1 := 'Blog';
  Nome2 := 'codedelphi';

  Memo2.Clear;
  Memo2.Lines.Add('Iniciando com');
  Memo2.Lines.Add('X = '+Nome1);
  Memo2.Lines.Add('Y = '+Nome2);

  Memo2.Lines.Add('Trocando para');
  Trocar<String>(Nome1, Nome2);
  Memo2.Lines.Add('X = '+ Nome1);
  Memo2.Lines.Add('Y = '+ Nome2); // Saída: Nome1 = codedelphi, Nome2 = Blog

end;

Neste exemplo, o procedimento Trocar<T> pode ser usado para trocar o valor de duas variáveis de qualquer tipo. A flexibilidade dos métodos genéricos permite que o mesmo código funcione com inteiros, strings ou outros tipos de dados.

Veja abaixo a ilustração do projeto:

Ilustração do projeto.

Código fonte do exemplo

Você pode fazer o download do exemplo do projeto através do repositório do github:

https://github.com/Gisele-de-Melo/Metodos_Generics

Vantagens de Usar Classes e Métodos Genéricos

  • Reutilização de Código: Uma das maiores vantagens de usar Generics é a capacidade de reutilizar código sem duplicação. Com classes e métodos genéricos, você pode criar componentes que funcionam com qualquer tipo de dado.
  • Segurança de Tipo: Diferente de usar tipos variantes, os Generics garantem a segurança do tipo em tempo de compilação. Isso significa que você evita erros de tipo durante a execução, tornando o código mais robusto.
  • Melhor Manutenção: Como você escreve menos código e evita duplicação, a manutenção do software é simplificada. Alterações no comportamento da classe ou método genérico afetam todos os tipos de dados que utilizam aquele código.

Limitações de Generics

Embora os Generics tragam muitas vantagens, eles têm algumas limitações no Delphi:

  • Falta de RTTI (Runtime Type Information): Em Delphi, Generics não possuem suporte completo para RTTI, o que pode limitar a capacidade de realizar operações como serialização.
  • Complexidade: O uso excessivo de Generics pode tornar o código mais complexo e difícil de entender, especialmente para desenvolvedores que não estão familiarizados com essa funcionalidade.

Conclusão

Classes e métodos genéricos em Delphi são uma poderosa ferramenta para promover a reutilização de código e flexibilidade no desenvolvimento. Eles permitem que você crie componentes que podem ser usados com qualquer tipo de dado, melhorando a eficiência e a manutenção do código. Neste artigo, mostramos como implementar e instanciar classes genéricas, além de demonstrar um método genérico que pode ser usado em diversos tipos de dados.

Ao dominar o uso de Generics, você pode desenvolver aplicativos mais eficientes e escaláveis, com código mais limpo e reutilizável.

Posts Relacionados


Livros + e-books

Delphi para Android e iOS

codedelphi.com
codedelphi.com

Delphi Start

codedelphi.com

Programando em Delphi XE

Aprenda programar Delphi

Banco de Dados RAD Delphi

Delphi Programming Projects

Deixe um comentário