TypeScript POO Intermediário
Classes abstratas
Em TypeScript, uma classe abstrata é uma classe que não pode ser instanciada diretamente e serve como base para outras classes. Ela pode conter métodos abstratos (sem implementação) que as subclasses são obrigadas a implementar, além de métodos concretos com código compartilhado.
A palavra-chave abstract marca tanto a classe quanto seus métodos abstratos. Métodos abstratos só podem existir em classes abstratas e não têm corpo. Classes concretas que herdam de uma classe abstrata precisam implementar todos os métodos abstratos, a menos que também sejam abstratas.
A diferença entre classe abstrata e interface é que a classe abstrata pode ter implementação de métodos e estado (propriedades), enquanto a interface define apenas o contrato (métodos e propriedades sem implementação). Uma classe pode estender apenas uma classe abstrata, mas pode implementar várias interfaces.
O padrão Template Method é um uso clássico de classes abstratas: a classe base define o esqueleto de um algoritmo em um método concreto, chamando métodos abstratos que as subclasses implementam. Assim, a estrutura do algoritmo fica fixa na base, mas partes específicas variam nas subclasses.
Pontos-chave
abstract classnão pode ser instanciada comnew; serve apenas como base para herança.- Métodos
abstractnão têm corpo e obrigam as subclasses concretas a implementá-los. - Classes abstratas podem ter métodos concretos, propriedades e construtores; interfaces não.
- Uma classe pode estender uma única classe abstrata, mas implementar várias interfaces.
- O padrão Template Method usa métodos abstratos para permitir variação de partes de um algoritmo.
abstract class ProcessadorPagamento {
// Método concreto que define o esqueleto do algoritmo (Template Method)
processar(valor: number): void {
if (!this.validar(valor)) {
console.log("Pagamento inválido");
return;
}
this.debitar(valor);
this.notificar(valor);
}
// Método abstrato: cada subclasse implementa sua validação
protected abstract validar(valor: number): boolean;
// Método abstrato: cada subclasse implementa o débito
protected abstract debitar(valor: number): void;
// Método concreto com comportamento padrão
protected notificar(valor: number): void {
console.log(`Notificação enviada para pagamento de R$ ${valor}`);
}
}
class CartaoCredito extends ProcessadorPagamento {
protected validar(valor: number): boolean {
return valor > 0 && valor <= 5000;
}
protected debitar(valor: number): void {
console.log(`Cartão de crédito debitado em R$ ${valor}`);
}
}
class Pix extends ProcessadorPagamento {
protected validar(valor: number): boolean {
return valor > 0;
}
protected debitar(valor: number): void {
console.log(`Pix transferido no valor de R$ ${valor}`);
}
}
// Uso
const cartao = new CartaoCredito();
cartao.processar(1000);
const pix = new Pix();
pix.processar(2000);
// cartao.processar(6000); // saída: Pagamento inválido