W3docs

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:

  1. Herdar membros do pai sem alterações.
  2. Adicionar novas propriedades e métodos próprios.
  3. 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)
Result

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 public são herdados e utilizáveis em qualquer lugar.
  • Membros protected são herdados e acessíveis dentro da classe filha, mas não de fora da classe.
  • Membros private nã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 100
Result

Veja 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 private no pai é invisível para a classe filha; torne-a protected se 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

Prática

Prática
Qual é o significado da palavra-chave 'extends' em PHP?
Qual é o significado da palavra-chave 'extends' em PHP?
Was this page helpful?