Entendendo a Programação Orientada a Objetos em PHP: o Conceito de Classes Abstratas
Aprenda o que são classes abstratas em PHP, como declará-las com a palavra-chave abstract e quando usá-las em vez de interfaces.
Em PHP, a programação orientada a objetos (POO) ajuda você a escrever código limpo, organizado e fácil de manter. Um dos blocos de construção mais importantes da POO é a classe abstrata — uma classe que define um contrato compartilhado para uma família de classes relacionadas, sem poder ser usada sozinha.
Este capítulo explica o que é uma classe abstrata, como declará-la com a palavra-chave abstract, como os métodos abstract obrigam as classes filhas a fornecer uma implementação e quando vale a pena usar uma classe abstrata em vez de uma interface.
O que é uma classe abstrata?
Uma classe abstrata é um modelo para criar objetos, mas não pode ser instanciada diretamente. Em vez disso, ela serve de base da qual outras classes herdam propriedades e métodos comuns. Ela pode combinar dois tipos de métodos:
- Métodos concretos — métodos totalmente implementados, que todas as classes filhas herdam como estão.
- Métodos abstratos — métodos que declaram apenas uma assinatura (nome, visibilidade e parâmetros), sem corpo. Toda classe filha não abstrata deve implementá-los.
Essa combinação permite que a classe pai imponha o que precisa existir, deixando o como funciona a cargo de cada classe filha — a base do polimorfismo em PHP. Se você está começando com herança, leia primeiro Herança em PHP.
Benefícios de usar classes abstratas
- Encapsulamento: as classes abstratas podem encapsular propriedades e métodos comuns, facilitando a manutenção da consistência entre classes relacionadas.
- Reutilização de código: o mecanismo de herança da POO permite criar novas classes estendendo classes existentes, inclusive classes abstratas. Isso reduz a quantidade de código a ser escrito e aumenta a eficiência do desenvolvimento.
- Design aprimorado: ao usar classes abstratas, os desenvolvedores conseguem criar uma hierarquia clara de classes, o que facilita entender as relações entre as diferentes partes do código.
- Flexibilidade: ao definir uma classe abstrata, os desenvolvedores podem especificar quais propriedades e métodos devem existir em uma classe derivada, deixando os detalhes de implementação para ela. Isso oferece certa flexibilidade e permite criar classes personalizadas para finalidades específicas.
Como definir uma classe abstrata em PHP
Para criar uma classe abstrata em PHP, coloque a palavra-chave abstract antes da declaração class. Marque também com abstract qualquer método que as classes filhas precisem implementar — um método abstrato termina com ponto e vírgula e não tem corpo { }.
Exemplo de classe abstrata em PHP
abstract class Shape {
// Concrete method: shared by every child as-is.
public function describe(): string {
return "A shape with area " . $this->getArea();
}
// Abstract method: each child must implement it.
abstract public function getArea(): float;
}Aqui, Shape é declarada como abstract, portanto não pode ser transformada diretamente em um objeto. Ela oferece um método describe() pronto para todas as classes filhas, enquanto getArea() permanece abstrato — toda subclasse concreta precisa fornecer a sua própria versão.
Classes abstratas não podem ser instanciadas
Tentar criar um objeto a partir de uma classe abstrata gera um erro fatal:
$shape = new Shape(); // Fatal error: Cannot instantiate abstract class ShapeÉ exatamente esse o objetivo: uma classe abstrata fica incompleta até que uma classe filha implemente seus métodos abstratos. A visibilidade de um método abstrato (public, protected) também é imposta — a classe filha não pode torná-la mais restritiva. Consulte Modificadores de acesso em PHP para conhecer as regras de visibilidade.
Estendendo uma classe abstrata em PHP
Para estender uma classe abstrata, use a palavra-chave extends e implemente todos os métodos abstratos. A classe filha também pode adicionar seu próprio construtor e membros extras.
Estendendo uma classe abstrata em PHP
class Rectangle extends Shape {
public function __construct(
protected float $width,
protected float $height
) {}
public function getArea(): float {
return $this->width * $this->height;
}
}
class Circle extends Shape {
public function __construct(protected float $radius) {}
public function getArea(): float {
return M_PI * $this->radius ** 2;
}
}Tanto Rectangle quanto Circle estendem Shape e fornecem o seu próprio getArea(). Ambas herdam o método concreto describe() sem precisar reescrevê-lo.
E se uma classe filha esquecer um método abstrato?
Se uma classe filha não abstrata não implementar todos os métodos abstratos, o PHP se recusa a compilar o arquivo:
class Triangle extends Shape {} // Fatal error: Class Triangle contains 1
// abstract method and must therefore be
// declared abstract or implement getArea()O compilador detecta o método ausente antes mesmo de o seu código ser executado — essa garantia é o que torna as classes abstratas úteis para impor um contrato.
Usando uma classe abstrata
Você nunca instancia a própria classe abstrata — você instancia uma classe filha concreta e chama os métodos dela. Como todas as classes filhas respeitam o mesmo contrato, é possível tratá-las de maneira uniforme (polimorfismo):
Exemplo de uso de uma classe abstrata em PHP
$shapes = [
new Rectangle(10, 5),
new Circle(3),
];
foreach ($shapes as $shape) {
echo round($shape->getArea(), 2), "\n";
}
// Output:
// 50
// 28.27Cada objeto resolve getArea() para a sua própria implementação, enquanto describe() (herdado de Shape) funciona da mesma forma para todos eles.
Classe abstrata vs. interface
As classes abstratas e as interfaces definem um contrato, mas há diferenças entre elas:
| Característica | Classe abstrata | Interface |
|---|---|---|
| Pode conter métodos implementados | Sim | Não — os métodos são apenas assinaturas (sem corpo) |
| Pode ter propriedades / estado | Sim | Somente constantes |
| Quantas uma classe pode ter | Uma (herança simples) | Várias (implements A, B) |
| Quando usar | As classes filhas compartilham código e um contrato | Você só precisa de um contrato, possivelmente entre classes não relacionadas |
Use uma classe abstrata quando classes relacionadas compartilham implementação real; use uma interface quando você só quer garantir que um conjunto de métodos exista. Veja Interfaces em PHP e Classes e objetos em PHP para saber mais.
Conclusão
As classes abstratas oferecem uma forma de impor consistência e estrutura ao seu código PHP e trazem diversos benefícios, como encapsulamento, reutilização de código, design aprimorado e flexibilidade. Seja você um desenvolvedor PHP experiente ou alguém que está começando agora, entender o conceito de classes abstratas é um passo importante para dominar a POO em PHP.