No Delphi, a declaração de tipos de classe oferece uma estrutura robusta para a programação orientada a objetos. A sintaxe fundamental para definir uma classe é a seguinte:
type
NomeDaClasse = class [(ClassePai)]
// Seções de membros (private, protected, public, published, strict private/public)
// Declarações de campos, métodos, propriedades
end;
Modificadores de Classe: Abstract e Sealed
Os modificadores abstract e sealed influenciam diretamente o comportamento e a capacidade de herança de uma classe. Uma classe não pode ser declarada simultaneamente como abstract e sealed, pois suas finalidades são mutuamente exclusivas.
Classes Abstratas (abstract)
Um tipo de classe pode ser marcado como abstract. Embora o Delphi permita a instanciação de classes abstratas por questões de compatibilidade retroativa, essa prática é desencorajada em projetos modernos. Uma classe abstrata é tipicamente projetada para ser herdada, com a intenção de que suas subclasses forneçam implementações concretas para métodos abstratos.
Classes Seladas (sealed)
Uma classe declarada como sealed não permite que outras classes herdem dela. Isso impede a extensão da funcionalidade da classe por meio de herança, garantindo que o comportamento seja finalizado e não possa ser alterado por subclasses. Esse modificador é útil para projetar classes que representam conceitos finalizados ou para otimizações de segurança e desempenho.
type
// Classe base abstrata, não pode ser instanciada diretamente com uso moderno
TRegistroBase = class abstract
private
FIdentificador: Integer;
public
constructor Create(aId: Integer);
procedure ProcessarDados; virtual; abstract; // Método abstrato
property Identificador: Integer read FIdentificador;
end;
// Exemplo de classe concreta que herda de TRegistroBase
TRegistroTexto = class(TRegistroBase)
private
FConteudo: string;
public
constructor Create(aId: Integer; const aConteudo: string);
procedure ProcessarDados; override;
property Conteudo: string read FConteudo;
end;
// Classe selada, não pode ser herdada
TEstritorLog = class sealed
public
procedure EscreverEntrada(const Mensagem: string);
end;
Herança de Classe ((ClassePai))
A seção (ClassePai) na declaração de classe é opcional. Se omitida, a nova classe herdará diretamente da classe predefinida System.TObject. Especificar uma ClassePai permite que a nova classe herde membros e implemente polimorfismo. Se uma classe herda de outra e não declara membros próprios, a palavra-chave end pode ser omitida.
Tipos e Constantes Aninhadas
O Delphi oferece suporte à declaração de tipos e constantes dentro de uma classe, conhecidos como tipos e constantes aninhadas. Essa funcionalidade permite agrupar logicamente elementos relacionados à classe, melhorando a organização do código e ajudando a evitar colisões de nomes no escopo global.
type
TGerenciadorConfig = class
public
// Tipo aninhado: Enumeração para estados de configuração
type
TStatusConfiguracao = (scNaoInicializado, scCarregado, scErro);
// Constante aninhada: Apenas constantes simbólicas são permitidas (e.g., const MaxTentativas = 5;)
const
MAX_CONFIG_FILES = 10;
NOME_PADRAO_ARQUIVO = 'config.ini'; // Exemplo de constante simbólica string
private
FEstadoAtual: TStatusConfiguracao;
FNumeroArquivos: Integer;
public
constructor Create;
procedure CarregarConfiguracao;
property EstadoAtual: TStatusConfiguracao read FEstadoAtual;
end;
É importante notar que, para constantes aninhadas, apenas constantes simbólicas são permitidas. Tentar declarar uma constante tipada (por exemplo, const MeuNumero: Integer = 20;) dentro de uma classe aninhada resultará em um erro de compilação.
Tipos de Objeto (Sintaxe Alternativa e Obsoleta)
O Delphi também oferece uma sintaxe alternativa para a declaração de tipos usando a palavra-chave object. Esta funcionalidade é primariamente mantida para compatibilidade retroativa com códigos mais antigos e é desaconselhada para o desenvolvimento de novas aplicações.
type
TRegistroAntigo = object [(ObjetoPai)]
// Declarações de campos, métodos, propriedades (sem seção published)
FChave: Integer;
FValor: string;
procedure SetDados(const aChave: Integer; const aValor: string);
end;
// Implementação de método para o tipo de objeto
procedure TRegistroAntigo.SetDados(const aChave: Integer; const aValor: string);
begin
FChave := aChave;
FValor := aValor;
end;
Ao contrário dos tipos de classe (declarados com class), os tipos de objeto (declarados com object):
- Não herdam de
System.TObjectpor padrão. Se(ObjetoPai)for omitido, o tipo de objeto não terá um ancestral. - Não possuem construtores, destrutores ou outros métodos embutidos.
- Não suportam a seção
publishedpara publicação de propriedades e eventos no ambiente de desenvolvimento visual.
Instâncias de tipos de objeto podem ser criadas usando os procedimentos New e destruídas com Dispose (similar à alocação de memória de ponteiros), ou podem ser declaradas diretamente como variáveis, comportando-se de forma semelhante a registros. Dada a sua natureza para compatibilidade e as funcionalidades mais ricas das classes, o uso de tipos de objeto deve ser evitado em novos projetos.