Herança em PHP OOP
Aprenda como funciona a herança em PHP OOP: sintaxe extends, sobrescrita de métodos, palavra-chave parent e exemplo completo.
A herança permite que uma classe reutilize as propriedades e métodos de outra, possibilitando modelar relacionamentos "é-um" (um Car é um Vehicle) sem duplicar código. Em PHP, ela é implementada com a palavra-chave extends. Este capítulo aborda a sintaxe, como funcionam a sobrescrita de métodos e a palavra-chave parent, como os construtores são herdados, o papel da visibilidade e da palavra-chave final, além de um exemplo completo e executável para você experimentar.
Se você ainda não conhece classes, comece com Classes e Objetos em PHP e depois volte aqui.
O que é Herança?
Herança é a capacidade de definir uma nova classe (a classe filha, subclasse ou classe derivada) com base em uma existente (a classe pai, superclasse ou classe base). A classe filha obtém automaticamente os membros public e protected da classe pai e pode:
- reutilizá-los como estão,
- sobrescrevê-los com sua própria implementação, ou
- adicionar novas propriedades e métodos.
PHP suporta apenas herança simples: uma classe pode estender exatamente um pai. No entanto, é possível criar uma cadeia — Hatchback extends Car extends Vehicle — e uma classe também pode implementar diversas interfaces quando for necessário comportamento de mais de uma fonte.
Benefícios da Herança
- Reusabilidade — a lógica compartilhada fica na classe pai, sendo escrita uma única vez.
- Manutenibilidade — uma correção na classe pai se propaga para todas as subclasses; menos duplicação significa menos lugares para bugs se esconderem.
- Polimorfismo — código que espera um
Vehiclefunciona com qualquer subclasse, permitindo trocar implementações livremente. - Modelagem clara — a hierarquia de classes documenta os relacionamentos "é-um" do seu domínio.
Sintaxe de Herança em PHP OOP
Para criar uma subclasse, escreva extends seguido do nome da classe pai:
class ChildClass extends ParentClass {
// child-specific properties and methods
}ChildClass agora possui todos os membros public e protected de ParentClass. Note que membros private do pai não são acessíveis a partir da classe filha — use protected quando quiser que as subclasses acessem um membro, mas mantendo-o oculto para código externo. Consulte Modificadores de Acesso em PHP para as regras completas de visibilidade.
Sobrescrevendo Métodos da Classe Pai
Uma subclasse sobrescreve um método da classe pai declarando um método com o mesmo nome. A versão da classe filha substitui a do pai para objetos dessa subclasse:
class ParentClass {
public function displayMessage() {
echo "Hello from ParentClass";
}
}
class ChildClass extends ParentClass {
public function displayMessage() {
echo "Hello from ChildClass";
}
}Chamando o método pai com parent::
Sobrescrever não significa necessariamente substituir — muitas vezes você quer estender o comportamento do pai. Use parent:: para chamar primeiro a versão do pai e então adicionar mais comportamento:
class ChildClass extends ParentClass {
public function displayMessage() {
parent::displayMessage(); // runs the parent's logic
echo " — and hello from ChildClass";
}
}Adicionar o atributo #[\Override] (PHP 8.3+) acima de um método instrui o PHP a falhar com um erro caso ele não sobrescreva de fato um método do pai — uma forma simples de capturar erros de digitação nos nomes dos métodos.
Herdando e Estendendo Construtores
Se uma classe filha não define seu próprio construtor, o construtor da classe pai é herdado e executado automaticamente. Se a classe filha define o seu próprio, o construtor do pai não é chamado automaticamente — você deve chamá-lo explicitamente com parent::__construct(...):
class Vehicle {
public function __construct(public string $make) {}
}
class Car extends Vehicle {
public function __construct(string $make, public string $fuelType) {
parent::__construct($make); // initialise the inherited part
}
}Para mais informações sobre construtores, consulte Construtor em PHP.
Impedindo Sobrescrita com final
Marque um método como final para impedir que subclasses o sobrescrevam, ou marque uma classe inteira como final para impedir que ela seja estendida:
class PaymentBase {
final public function transactionId(): string {
return 'TX-' . uniqid();
}
}Isso é útil para lógicas que devem se comportar de forma idêntica em todos os lugares. Consulte Palavra-chave final em PHP para mais detalhes. Quando o pai deve definir a assinatura de um método mas forçar cada filho a fornecer o corpo, use uma classe abstrata.
Exemplo de Herança em PHP OOP
Aqui está um programa completo e executável. Uma classe base Vehicle armazena os dados comuns, e uma subclasse Car adiciona uma propriedade fuelType e estende displayDetails() via parent:::
<?php
class Vehicle
{
public function __construct(
protected string $make,
protected string $model,
protected int $year
) {}
public function displayDetails(): void
{
echo "Make: {$this->make}\n";
echo "Model: {$this->model}\n";
echo "Year: {$this->year}\n";
}
}
class Car extends Vehicle
{
public function __construct(
string $make,
string $model,
int $year,
protected string $fuelType
) {
parent::__construct($make, $model, $year);
}
public function displayDetails(): void
{
parent::displayDetails(); // reuse the parent's output
echo "Fuel Type: {$this->fuelType}\n"; // then add our own
}
}
$car = new Car('Toyota', 'Corolla', 2023, 'Hybrid');
$car->displayDetails();Saída:
Make: Toyota
Model: Corolla
Year: 2023
Fuel Type: HybridCar herda make, model e year (declarados como protected, para que a subclasse possa usá-los), reutiliza o displayDetails() do pai via parent:: e adiciona a linha de fuelType por conta própria.
Armadilhas Comuns
privatenão é herdado. Uma propriedadeprivateda classe pai é invisível para a filha. Useprotectedse as subclasses precisarem acessá-la.- Construtores não são encadeados automaticamente quando a classe filha define o seu próprio — sempre chame
parent::__construct()explicitamente. - PHP não possui herança múltipla. Uma classe estende apenas um pai; use interfaces ou traits para compartilhar comportamento de múltiplas fontes.
- Sobrescrita ignora erros de digitação silenciosamente antes do PHP 8.3 — um nome de método com erro simplesmente cria um novo método em vez de sobrescrever. Adicione
#[\Override]para maior segurança.
Conclusão
A herança permite que uma subclasse reutilize, sobrescreva e estenda os membros de uma classe pai por meio da palavra-chave extends, com parent:: fornecendo acesso à implementação original. Combinada com modificadores de visibilidade, construtores e final, ela é a base da reutilização de código e do polimorfismo em PHP OOP. Em seguida, explore classes abstratas e interfaces para projetar hierarquias de classes mais limpas.