Menu

Tradução

Português English Español Français

Classes Abstratas em Delphi

Neste post, exploraremos o que são classes abstratas em Delphi, quando utilizá-las, a diferença entre classes abstratas e interfaces, e apresentaremos um exemplo prático de implementação em Delphi.

 

Classes Abstratas em Delphi
Formas geométricas - Classes Abstratas em Delphi

Introdução

As classes abstratas são um conceito fundamental na programação orientada a objetos e desempenham um papel crucial no design de software em Delphi. Neste artigo, exploraremos o que são classes abstratas em Delphi, quando utilizá-las, a diferença entre classes abstratas e interfaces, e apresentaremos um exemplo prático de implementação em Delphi.

O que são Classes Abstratas?

Uma classe abstrata é uma classe que não pode ser instanciada diretamente. Em vez disso, serve como uma classe base que outras classes podem herdar. Classes abstratas são usadas para definir um conjunto comum de métodos e propriedades que as subclasses devem implementar. Elas podem conter métodos implementados e métodos abstratos (não implementados).

Quando Usar Classes Abstratas?

Classes abstratas são particularmente úteis quando você tem uma base comum de funcionalidade que várias subclasses compartilham, mas cada subclasse deve fornecer sua própria implementação específica de certos métodos. Elas ajudam a garantir que todas as subclasses sigam a mesma estrutura, promovendo a consistência no design do software.

Diferença entre Classes Abstratas e Interfaces

Embora classes abstratas e interfaces possam parecer semelhantes, existem diferenças importantes entre elas:

  • Classes Abstratas: Podem conter tanto métodos implementados quanto métodos abstratos. As subclasses herdam a implementação e podem sobrescrever os métodos conforme necessário.
  • Interfaces: Apenas definem a assinatura dos métodos, sem qualquer implementação. As classes que implementam a interface devem fornecer a implementação de todos os métodos definidos na interface.

A principal diferença é que classes abstratas podem fornecer alguma implementação, enquanto interfaces não podem.

Palavras-Chave virtual e abstract em Delphi

Virtual

A palavra-chave virtual é usada para declarar que um método pode ser sobrescrito (overridden) em uma classe derivada. Quando um método é declarado como virtual, a classe base fornece uma implementação padrão que pode ser opcionalmente substituída em uma subclasse.

Abstract

A palavra-chave abstract é usada para declarar métodos que não possuem implementação na classe base. Um método abstract é, na verdade, uma assinatura de método que exige que qualquer subclasse forneça sua própria implementação.

Diferença entre virtual e abstract

  • virtual:
    • O método possui uma implementação padrão.
    • Pode ser opcionalmente sobrescrito em subclasses.
  • abstract:
    • O método não possui implementação na classe base.
    • Deve ser obrigatoriamente implementado em subclasses.

Compreender o uso de virtual e abstract é essencial para aproveitar ao máximo a programação orientada a objetos em Delphi. A palavra-chave virtual permite que métodos sejam sobrescritos, oferecendo flexibilidade e extensibilidade. A palavra-chave abstract, por outro lado, define um contrato obrigatório para as subclasses, garantindo que métodos específicos sejam implementados. Juntas, essas palavras-chave ajudam a criar estruturas de código robustas, reutilizáveis e de fácil manutenção.

Exemplo Prático de Classes Abstratas em Delphi

Vamos criar um exemplo prático em Delphi para ilustrar o uso de classes abstratas. Suponha que estamos desenvolvendo uma aplicação para gerenciar formas geométricas. Queremos ter uma classe base abstrata TShape que define métodos comuns como CalculateArea e CalculatePerimeter, e subclasses TCircle e TRectangle que implementam esses métodos.

Configurando o Ambiente

  1. Abrindo o Delphi: Abra o Delphi e crie um novo projeto VCL Forms Application e salve com o nome de prjAbstractExample.
  2. Criando as Units: Adicione 2 units no seu projeto e salve com os seguintes nomes, unit1 = UBasicShape, unit2 = UShapes, que conterão as classes TShape, TCircle e TRectangle.
  3. Configurando o Formulário Principal: Salve o formulário com o nome de UAbstracExample para unit e frmAbstractExample para o form. Adicione os seguintes componente ao formulário:
    • TButton(BtnCircle) - Caption Círculo
    • TButton(BtnRectangle) - Caption Retângulo
    • Label(LblCalculation) - Caption Informações
    • Memo(MmoCalculation)

Definindo a Classe Abstrata

Delphi

unit UBasicShape;

interface

type
  // Definindo a classe abstrata TShape
  TShape = class
  public
    // Métodos abstratos
    function CalculateArea: Double; virtual; abstract;
    function CalculatePerimeter: Double; virtual; abstract;
  end;

implementation

end.
  

Explicação:

  • TShape: Esta é a definição da classe base abstrata.
  • CalculateArea: Método abstrato que deve ser implementado por qualquer classe derivada. Ele calcula a área da forma.
  • CalculatePerimeter: Outro método abstrato que deve ser implementado por qualquer classe derivada. Ele calcula o perímetro da forma.
  • virtual; abstract: Indica que o método é virtual (pode ser sobrescrito) e abstrato (deve ser implementado em subclasses).

Implementando as Subclasses

Delphi

unit UShapes;

interface

uses
  UBasicShape, System.SysUtils;

type
  // Subclasse TCircle que herda de TShape
  TCircle = class(TShape)
  private
    FRadius: Double;
  public
    constructor Create(ARadius: Double);
    function CalculateArea: Double; override;
    function CalculatePerimeter: Double; override;
  end;

  // Subclasse TRectangle que herda de TShape
  TRectangle = class(TShape)
  private
    FWidth, FHeight: Double;
  public
    constructor Create(AWidth, AHeight: Double);
    function CalculateArea: Double; override;
    function CalculatePerimeter: Double; override;
  end;

implementation

{ TCircle }

constructor TCircle.Create(ARadius: Double);
begin
  FRadius := ARadius;
end;

function TCircle.CalculateArea: Double;
begin
  Result := Pi * FRadius * FRadius;
end;

function TCircle.CalculatePerimeter: Double;
begin
  Result := 2 * Pi * FRadius;
end;

{ TRectangle }

constructor TRectangle.Create(AWidth, AHeight: Double);
begin
  FWidth := AWidth;
  FHeight := AHeight;
end;

function TRectangle.CalculateArea: Double;
begin
  Result := FWidth * FHeight;
end;

function TRectangle.CalculatePerimeter: Double;
begin
  Result := 2 * (FWidth + FHeight);
end;

end.
  

Explicação da classe TCircle:

  • TCircle: Define uma classe derivada de TShape.
  • FRadius: Campo privado que armazena o raio do círculo.
  • Create: Construtor que inicializa o raio do círculo.
  • CalculateArea: Implementação que calcula a área do círculo usando a fórmula π * r^2.
  • CalculatePerimeter: Implementação que calcula o perímetro do círculo usando a fórmula 2 * π * r.
  • override: Indica que este método substitui a versão abstrata definida na classe base TShape.

Explicação da classe TRectangle:

  • TRectangle: Define uma classe derivada de TShape.
  • FWidth, FHeight: Campos privados que armazenam a largura e a altura do retângulo.
  • Create: Construtor que inicializa a largura e a altura do retângulo.
  • CalculateArea: Implementação que calcula a área do retângulo usando a fórmula largura * altura.
  • CalculatePerimeter: Implementação que calcula o perímetro do retângulo usando a fórmula 2 * (largura + altura).
  • override: Indica que este método substitui a versão abstrata definida na classe base TShape.

Utilizando as Classes

Agora, vamos ver como podemos usar essas classes em uma aplicação Delphi.

Delphi

unit UAbstracExample;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, UShapes;

type
  TfrmAbstracExample = class(TForm)
    ButtonCircle: TButton;
    ButtonRectangle: TButton;
    LblCalculation: TLabel;
    MmoCalculation: TMemo;
    procedure ButtonCircleClick(Sender: TObject);
    procedure ButtonRectangleClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmAbstracExample: TfrmAbstracExample;

implementation

{$R *.dfm}

procedure TfrmAbstracExample.ButtonCircleClick(Sender: TObject);
var
  Circle: TCircle;
begin
  Circle := TCircle.Create(5.0);
  try
    MmoCalculation.Lines.Add('Circle Area: ' + FloatToStr(Circle.CalculateArea));
    MmoCalculation.Lines.Add('Circle Perimeter: ' + FloatToStr(Circle.CalculatePerimeter));
  finally
    Circle.Free;
  end;
end;

procedure TfrmAbstracExample.ButtonRectangleClick(Sender: TObject);
var
  Rectangle: TRectangle;
begin
  Rectangle := TRectangle.Create(4.0, 6.0);
  try
    MmoCalculation.Lines.Add('Rectangle Area: ' + FloatToStr(Rectangle.CalculateArea));
    MmoCalculation.Lines.Add('Rectangle Perimeter: ' + FloatToStr(Rectangle.CalculatePerimeter));
  finally
    Rectangle.Free;
  end;
end;

end.
  

Explicação:

  • UAbstracExample: Define uma unidade que utiliza as classes TCircle e TRectangle.
  • BtnCircleClick: Evento que demonstra a criação e o uso de objetos TCircle.
  • BtnRectangleClick: Evento que demonstra a criação e o uso de objetos TRectangle.
  • LblCalculation: Rótulo para o componente Memo(MmoCalculation).
  • Circle: Instância de TCircle criada com raio 5.
  • Rectangle: Instância de TRectangle criada com largura 4 e altura 6.
  • MmoCalculation: O memo exibe informações mostrando a área e o perímetro das formas criadas.
  • Free: Libera a memória alocada para os objetos Circle e Rectangle.

Você pode melhorar esse projeto inserindo caixas de texto para informar o raio do círculo, a largura e altura do retângulo, deixando o projeto flexível para executar os cálculos das informações inseridas. É uma forma de você estudar, adquirir mais conhecimento e de quebra ter uma calculadora que faz cálculos de área e perímetro de círculos e retângulos.


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/ClassesAbstratas

Conclusão

As classes abstratas são uma poderosa ferramenta na programação orientada a objetos em Delphi. Elas permitem definir uma estrutura comum para subclasses, promovendo a consistência e reutilização de código. Diferenciando-se das interfaces, as classes abstratas podem fornecer implementações parciais que as subclasses podem aproveitar. Compreender e aplicar corretamente as classes abstratas pode tornar seu código mais organizado, flexível e fácil de manter. Se você está começando com Delphi ou aprimorando suas habilidades, entender e usar classes abstratas é um passo fundamental na sua jornada de desenvolvimento.

Posts Relacionados



Nenhum comentário:

Postar um comentário

Recursividade em Delphi: Conceitos, Exemplos e Aplicações Práticas

Neste post, você aprenderá quando usar recursividade em Delphi, suas vantagens e desvantagens, além de um exemplo prático implementa...