extends
A palavra-chave "extends" em PHP permite que uma classe filha herde propriedades e métodos de uma classe pai na programação orientada a objetos.
A palavra-chave extends do PHP
extends é a forma como uma classe declara herança em PHP: uma classe filha (ou subclasse) construída com extends ganha automaticamente as propriedades e métodos não-privados da sua classe pai (ou superclasse). Em vez de copiar código compartilhado para cada classe relacionada, você o escreve uma vez na classe pai e deixa as subclasses especializá-lo.
Esta página aborda a sintaxe, como chamar o código do pai com parent::, como funciona a substituição de métodos, as regras de modificadores de acesso que determinam o que uma classe filha herda e os erros comuns que as pessoas cometem. O PHP suporta herança simples apenas — uma classe pode extends exatamente um pai (use interfaces quando precisar que um tipo desempenhe vários papéis).
Sintaxe
class ChildClass extends ParentClass {
// additional or overriding members
}A classe filha pode fazer três coisas:
- Herdar membros do pai sem alterações.
- Adicionar novas propriedades e métodos próprios.
- Substituir um método herdado redeclarando-o com o mesmo nome.
Um primeiro exemplo
<?php
class Fruit {
public $name;
public $color;
public function __construct($name, $color) {
$this->name = $name;
$this->color = $color;
}
public function getInfo() {
echo "This fruit is a {$this->name} and it is {$this->color}.";
}
}
// Apple inherits everything from Fruit and overrides getInfo().
class Apple extends Fruit {
public function getInfo() {
echo "This fruit is an {$this->name} and it is {$this->color}.";
}
}
$apple = new Apple("apple", "red");
$apple->getInfo();
// Output: This fruit is an apple and it is red.Apple nunca declara $name, $color ou um construtor — ela os herda de Fruit. Ela apenas redefine getInfo(), o que substitui a versão do pai.
Chamando o pai com parent::
Uma classe filha frequentemente quer estender o comportamento do pai em vez de substituí-lo. Quando uma classe filha define seu próprio construtor, o PHP não chama o construtor do pai automaticamente — você deve chamá-lo explicitamente com parent::__construct(). A mesma sintaxe parent:: funciona para qualquer método substituído.
<?php
class Car {
public $model;
public $year;
public function __construct($model, $year) {
$this->model = $model;
$this->year = $year;
}
public function getInfo() {
echo "This car is a {$this->model} from {$this->year}.";
}
}
class Toyota extends Car {
public function __construct($year) {
// Fill in the model, defer the rest to the parent.
parent::__construct("Toyota", $year);
}
public function getInfo() {
parent::getInfo(); // reuse the parent's output...
echo " (built by Toyota)"; // ...then add to it.
}
}
$toyota = new Toyota(2021);
$toyota->getInfo();
// Output: This car is a Toyota from 2021. (built by Toyota)Se Toyota não tivesse nenhum construtor, ela herdaria o construtor de Car e você a criaria com new Toyota("Corolla", 2021).
O que uma classe filha pode — e não pode — herdar
Os modificadores de acesso determinam a visibilidade através do limite de herança:
- Membros
publicsão herdados e utilizáveis em qualquer lugar. - Membros
protectedsão herdados e acessíveis dentro da classe filha, mas não de fora da classe. - Membros
privatenão são acessíveis na classe filha. Eles ainda existem no object, mas a classe filha não pode vê-los pelo nome.
<?php
class Account {
public $owner = "Ann";
protected $balance = 100; // visible to children
private $pin = "1234"; // hidden from children
public function reveal() {
return "$this->owner, balance $this->balance, pin $this->pin";
}
}
class SavingsAccount extends Account {
public function summary() {
// $this->balance works (protected); $this->pin would be null/undefined.
return "{$this->owner} has {$this->balance}";
}
}
$s = new SavingsAccount();
echo $s->summary();
// Output: Ann has 100Veja modificadores de acesso PHP para as regras completas de public / protected / private.
Selando uma classe ou método com final
Use a palavra-chave final para impedir mais extensões. Uma final class não pode ser pai; um método final não pode ser substituído por uma subclasse. Isso é útil quando a substituição quebraria uma invariante da qual sua classe depende.
class PaymentGateway {
final public function charge() { /* must not be altered */ }
}Erros comuns
- Esquecer
parent::__construct(). Definir um construtor na classe filha oculta o construtor do pai. Se você esquecer de chamá-lo, as propriedades do pai ficam não inicializadas. - Herança simples.
class A extends B, Cé um erro de sintaxe. Componha comportamento com interfaces ou traits em vez disso. - Membros privados não são compartilhados. Uma propriedade
privateno pai é invisível para a classe filha; torne-aprotectedse as subclasses precisarem dela. - As assinaturas de substituição devem permanecer compatíveis. Um método substituto deve aceitar os mesmos (ou mais amplos) argumentos, ou o PHP emitirá um aviso.
Tópicos relacionados
- Herança PHP — o conceito mais amplo que
extendsimplementa. - Classes e Objetos PHP — os blocos de construção.
- Classes abstratas — pais que devem ser estendidos.
- Interfaces — contratos para classes não relacionadas.