Resumo : neste tutorial, você aprenderá sobre o método de substituição do PHP e como aplicá-lo de forma eficaz em seu script.
Introdução ao método de substituição do PHP
A substituição de método permite que uma classe filha forneça uma implementação específica de um método já fornecido por sua classe pai .
Para substituir um método, você redefine esse método na classe filha com o mesmo nome, parâmetros e tipo de retorno.
O método na classe pai é chamado de método substituído, enquanto o método na classe filha é conhecido como método de substituição . O código no método substituído substitui (ou substitui) o código no método substituído.
O PHP decidirá qual método (método substituído ou substituído) chamar com base no objeto usado para invocar o método.
- Se um objeto da classe pai invocar o método, o PHP executará o método substituído.
- Mas se um objeto da classe filha invocar o método, o PHP executará o método de substituição.
Vamos dar um exemplo para entender melhor a substituição de métodos.
O exemplo a seguir define a Robot
classe que possui um método público greet()
e a Android
classe que herda a Robot
classe:
<?php
class Robot
{
public function greet()
{
return 'Hello!';
}
}
class Android extends Robot
{
}
Linguagem de código: HTML, XML ( xml )
Quando você chama o greet()
método através da instância do Android, o PHP chama o greet()
método da Robot
classe:
<?php
$android = new Android();
echo $android->greet(); // Hello!
Linguagem de código: HTML, XML ( xml )
Este é um cenário típico de herança .
Às vezes, você deseja substituir completamente o comportamento do método da classe pai por um novo. Neste caso, você precisa substituir o método da classe pai.
Para substituir um método, você redefine o método na classe pai novamente na classe filha, mas usa uma lógica diferente.
O seguinte adiciona o greet()
método à Android
classe que retorna uma mensagem de saudação diferente:
<?php
class Robot
{
public function greet()
{
return 'Hello!';
}
}
class Android extends Robot
{
public function greet()
{
return 'Hi';
}
}
$robot = new Robot();
echo $robot->greet(); // Hello
$android = new Android();
echo $android->greet(); // Hi!
Linguagem de código: HTML, XML ( xml )
Como funciona
- Primeiro, invoque o
greet()
método de uma instância daRobot
classe, ogreet()
método daRobot
classe é executado. - Segundo, chame o
greet()
método de uma instância daAndroid
classe, ogreet()
método daAndroid
classe é executado.
O diagrama de classes a seguir ilustra o relacionamento entre as classes Robot
e :Android
Chame o método substituído no método substituído
Ao substituir um método, você terá duas versões do mesmo método: uma na classe pai e outra na classe filha.
Se você chamar o método da classe pai no método da classe filha, não poderá usar $this
palavras-chave como esta:
<?php
class Android extends Robot
{
public function greet()
{
$greeting = $this->greet();
return $greeting . ' from Android.';
}
}
Linguagem de código: HTML, XML ( xml )
A $this->greet()
vontade se chamará indefinidamente.
Para chamar o greet()
método da Robot
classe, você precisa usar o parent
com o operador de resolução de escopo (::
) como o seguinte:
<?php
class Android extends Robot
{
public function greet()
{
$greeting = parent::greet();
return $greeting . ' from Android.';
}
}
Linguagem de código: HTML, XML ( xml )
Neste exemplo, o greet()
método da classe Andoird chama o greet()
método da Robot
classe. Ele concatena a string retornada pelo greet()
método do Robot
método com uma string literal ' from Android.'
e retorna a string concatenada.
Mais sobre o método de substituição do PHP
Suponha que você precise definir uma nova CheckingAccount
classe que estenda a BankAccount
classe. O seguinte define a BankAccount
classe:
<?php
class BankAccount
{
private $balance;
public function __construct($amount)
{
$this->balance = $amount;
}
public function getBalance()
{
return $this->balance;
}
public function deposit($amount)
{
if ($amount > 0) {
$this->balance += $amount;
}
return $this;
}
public function withdraw($amount)
{
if ($amount > 0 && $amount <= $this->balance) {
$this->balance -= $amount;
return true;
}
return false;
}
}
Linguagem de código: HTML, XML ( xml )
O withdraw()
método verifica se o valor do saque é maior que zero e menor ou igual ao saldo atual antes de deduzi-lo do saldo.
Segundo, defina a CheckingAccount
classe que herda a BankAccount
classe. A CheckingAccount
classe também possui o withdraw()
método que substitui o withdraw()
método da BankAccount
classe:
<?php
class CheckingAccount extends BankAccount
{
private $minBalance;
public function __construct($amount, $minBalance)
{
if ($amount > 0 && $amount >= $minBalance) {
parent::__construct($amount);
$this->minBalance = $minBalance;
} else {
throw new InvalidArgumentException('amount must be more than zero and higher than the minimum balance');
}
}
public function withdraw($amount)
{
$canWithdraw = $amount > 0 &&
$this->getBalance() - $amount > $this->minBalance;
if ($canWithdraw) {
parent::withdraw($amount);
return true;
}
return false;
}
}
Linguagem de código: HTML, XML ( xml )
O withdraw()
método da CheckingAccount
classe verifica o valor do saque em relação ao saldo mínimo antes de deduzi-lo.
O diagrama de classes a seguir ilustra o relacionamento entre as classes BankAccount e CheckingAccount:
O método final
Para evitar que o método da classe filha substitua o método da classe pai, você pode prefixar o método com a final
palavra-chave:
public final function methodName()
{
//...
}
Linguagem de código: PHP ( php )
O seguinte adiciona o id()
método à classe Robot:
class Robot
{
public function greet()
{
return 'Hello!';
}
final public function id()
{
return uniqid();
}
}
Linguagem de código: PHP ( php )
Se você tentar substituir o id()
método da Android
classe, receberá um erro. Por exemplo:
class Android extends Robot
{
public function greet()
{
$greeting = parent::greet();
return $greeting . ' from Andoid.';
}
public function id()
{
return uniqid('Android-');
}
}
Linguagem de código: PHP ( php )
Erro:
Cannot override final method Robot::id()
Linguagem de código: PHP ( php )
Resumo
- A substituição de método permite que uma classe filha defina um método que substitui (ou substitui) o método já fornecido por sua classe pai.
- Use
parent::
para chamar o método substituído no método substituído. - Use o método final quando não quiser que o método de uma classe filha substitua o método de uma classe pai.