POO 2.7: interfaces e classes abstratas

Interfaces e Classes Abstratas são ferramentas poderosas na Programação Orientada a Objetos (POO). Elas são usadas para definir contratos e criar estruturas flexíveis e reutilizáveis.
- Interfaces: Representam contratos que as classes devem cumprir, definindo métodos sem implementá-los.
- Classes Abstratas: São classes que podem conter tanto métodos abstratos (sem implementação) quanto métodos concretos. Elas não podem ser instanciadas diretamente.
Exemplo Prático: Sistema de Pagamentos
Neste exemplo, implementaremos um sistema de pagamentos onde diferentes formas de pagamento (como cartão e boleto) compartilham uma interface comum.
Definindo a Interface
unit IPagamentoUnit;
interface
type
IPagamento = interface
['{4D36E964-E325-11CE-BFC1-08002BE10318}'] // GUID único
procedure ProcessarPagamento(Valor: Currency);
function ObterDetalhes: string;
end;
implementation
end.
['{...}']: Identificador único para a interface, necessário em Delphi e Lazarus.- Métodos: Não possuem implementação, garantindo que todas as classes que implementarem a interface cumpram o contrato.
Criando Classes que Implementam a Interface
unit PagamentosUnit;
interface
uses
IPagamentoUnit, SysUtils;
type
TPagamentoCartao = class(TInterfacedObject, IPagamento)
private
FNumeroCartao: string;
public
constructor Create(NumeroCartao: string);
procedure ProcessarPagamento(Valor: Currency);
function ObterDetalhes: string;
end;
TPagamentoBoleto = class(TInterfacedObject, IPagamento)
private
FCodigoBarras: string;
public
constructor Create(CodigoBarras: string);
procedure ProcessarPagamento(Valor: Currency);
function ObterDetalhes: string;
end;
implementation
{ TPagamentoCartao }
constructor TPagamentoCartao.Create(NumeroCartao: string);
begin
FNumeroCartao := NumeroCartao;
end;
procedure TPagamentoCartao.ProcessarPagamento(Valor: Currency);
begin
WriteLn(Format('Pagamento de %.2f processado com cartão: %s',
[Valor, FNumeroCartao]));
end;
function TPagamentoCartao.ObterDetalhes: string;
begin
Result := 'Cartão de Crédito: ' + FNumeroCartao;
end;
{ TPagamentoBoleto }
constructor TPagamentoBoleto.Create(CodigoBarras: string);
begin
FCodigoBarras := CodigoBarras;
end;
procedure TPagamentoBoleto.ProcessarPagamento(Valor: Currency);
begin
WriteLn(Format('Pagamento de %.2f processado com boleto: %s',
[Valor, FCodigoBarras]));
end;
function TPagamentoBoleto.ObterDetalhes: string;
begin
Result := 'Boleto: ' + FCodigoBarras;
end;
end.
Criando uma Classe Abstrata
unit PagamentoAbstratoUnit;
interface
type
TPagamentoBase = class abstract
public
procedure ProcessarPagamento(Valor: Currency); virtual; abstract;
function ObterDetalhes: string; virtual; abstract;
end;
TPagamentoPix = class(TPagamentoBase)
private
FChavePix: string;
public
constructor Create(ChavePix: string);
procedure ProcessarPagamento(Valor: Currency); override;
function ObterDetalhes: string; override;
end;
implementation
{ TPagamentoPix }
constructor TPagamentoPix.Create(ChavePix: string);
begin
FChavePix := ChavePix;
end;
procedure TPagamentoPix.ProcessarPagamento(Valor: Currency);
begin
WriteLn(Format('Pagamento de %.2f processado via Pix: %s',
[Valor, FChavePix]));
end;
function TPagamentoPix.ObterDetalhes: string;
begin
Result := 'Pix: ' + FChavePix;
end;
end.
Exemplo de Uso
program ExemploInterfacesEClassesAbstratas;
uses
IPagamentoUnit, PagamentosUnit, PagamentoAbstratoUnit, SysUtils;
var
Pagamento: IPagamento;
PagamentoPix: TPagamentoBase;
begin
// Usando a interface
Pagamento := TPagamentoCartao.Create('1234-5678-9012-3456');
Pagamento.ProcessarPagamento(500.00);
WriteLn(Pagamento.ObterDetalhes);
Pagamento := TPagamentoBoleto.Create('12345678901234567890123456789012345678901234');
Pagamento.ProcessarPagamento(300.00);
WriteLn(Pagamento.ObterDetalhes);
// Usando a classe abstrata
PagamentoPix := TPagamentoPix.Create('[email protected]');
PagamentoPix.ProcessarPagamento(200.00);
WriteLn(PagamentoPix.ObterDetalhes);
// Liberação automática para objetos baseados em interfaces
end.
Explicação
- Interfaces:
- O código que utiliza as classes não precisa saber os detalhes de implementação, apenas que elas seguem o contrato definido pela interface.
- Classes Abstratas:
- São úteis quando você deseja compartilhar comportamento comum entre classes derivadas, mas ainda requer personalizações específicas.
Conclusão
- Interfaces: Perfeitas para desacoplar sistemas e criar contratos claros entre classes.
- Classes Abstratas: Permitem compartilhar implementações e definir padrões para classes derivadas.
💬 O que você achou deste conteúdo?
Se ficou com alguma dúvida ou quiser compartilhar sua experiência, deixe seu comentário abaixo! 👇
Sua participação enriquece a discussão e ajuda outros leitores também. 🚀😊
😊 Gostou do conteúdo?
Compartilhe com seus colegas de programação e deixe seu comentário com dúvidas ou sugestões!
#Programação #POO #Delphi #Lazarus #Pascal #Interfaces
#Desenvolvimento #BackEnd #CarreiraTech #DicasDeCódigo
#CursoPOO #GiovaniDaCruz
Continue o curso no próximo post!