Sobrescrita de Método
Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy — lição 23 de 91.
Às vezes, o método herdado de uma classe pai não se ajusta perfeitamente ao que a classe filha precisa. A sobrescrita de método (method overriding) permite que uma classe filha forneça sua própria implementação de um método que já existe na classe pai.
Para sobrescrever um método, basta definir um método na classe filha com o mesmo nome do método da classe pai:
<?php
class Animal {
public $name;
public function __construct($name) {
$this->name = $name;
}
public function speak() {
return "$this->name makes a sound";
}
}
class Cat extends Animal {
public function speak() {
return "$this->name says meow";
}
}
$cat = new Cat("Whiskers");
echo $cat->speak();
Saída:
Whiskers says meowA classe Cat substitui completamente o método speak() do pai por sua própria versão. Quando você chama speak() em um objeto cat, o PHP usa a implementação do filho.
Você também pode estender o comportamento da classe pai combinando parent:: com sua própria lógica:
<?php
class Dog extends Animal {
public function speak() {
return parent::speak() . " - woof woof!";
}
}
$dog = new Dog("Rex");
echo $dog->speak();
Saída:
Rex makes a sound - woof woof!Ponto Chave: A sobrescrita de métodos permite que classes filhas personalizem o comportamento herdado. Você pode substituir completamente um método ou usar parent:: para complementar a implementação original.
Desafio
FácilVamos construir um sistema de notificação que demonstra como as classes filhas podem substituir completamente ou estender os métodos dos pais por meio da sobrescrita de métodos (method overriding).
Você criará três arquivos que trabalham juntos para enviar diferentes tipos de notificações, cada um com seu próprio comportamento exclusivo:
Notification.php— Defina uma classeNotificationque serve como base para todos os tipos de notificação. Ela deve ter uma propriedade pública$recipiente um construtor que aceita e define o destinatário. Inclua um métodosend($message)que retorna"Sending to [recipient]: [message]".UrgentNotification.php— Defina uma classeUrgentNotificationque estendeNotification. Inclua o arquivo Notification no topo. Esta classe deve substituir completamente o métodosend($message)para retornar"URGENT to [recipient]: [message]!!!"— observe o prefixo "URGENT" e os pontos de exclamação no final. Isso demonstra a substituição total do comportamento do pai.LoggedNotification.php— Defina uma classeLoggedNotificationque estendeNotification. Inclua o arquivo Notification no topo. Esta classe deve sobrescreversend($message), mas basear-se na implementação do pai: chameparent::send($message)e anexe" [logged]"ao resultado. Isso demonstra a extensão em vez da substituição do comportamento.
Em main.php, inclua todos os três arquivos de classe de notificação. Você receberá duas entradas: o nome do destinatário e a mensagem a ser enviada. Crie uma instância de cada tipo de notificação (todas usando o mesmo destinatário) e, em seguida, chame send() com a mensagem em cada uma. Imprima cada resultado em sua própria linha nesta ordem: notificação regular, notificação urgente e, em seguida, notificação registrada (logged).
Este desafio mostra ambas as abordagens para a sobrescrita de métodos — a UrgentNotification substitui completamente a lógica do pai por sua própria formatação, enquanto a LoggedNotification usa parent:: para manter o comportamento original e adicioná-lo.
Folha de consulta
A sobreposição de método (method overriding) permite que uma classe filha forneça sua própria implementação de um método herdado de uma classe pai.
Para sobrepor um método, defina um método na classe filha com o mesmo nome do método da classe pai:
<?php
class Animal {
public function speak() {
return "makes a sound";
}
}
class Cat extends Animal {
public function speak() {
return "says meow";
}
}
A classe filha substitui completamente a implementação do método da classe pai. Quando chamado em um objeto filho, o PHP usa a versão da classe filha.
Para estender o comportamento do pai em vez de substituí-lo, use parent:: para chamar o método pai e adicionar sua própria lógica:
<?php
class Dog extends Animal {
public function speak() {
return parent::speak() . " - woof woof!";
}
}
Isso combina o comportamento original do pai com a funcionalidade adicional da classe filha.
Experimente você mesmo
<?php
require_once 'Notification.php';
require_once 'UrgentNotification.php';
require_once 'LoggedNotification.php';
// Ler a entrada
$recipient = trim(fgets(STDIN));
$message = trim(fgets(STDIN));
// TODO: Criar uma instância de cada tipo de notificação (todas usando o mesmo destinatário)
// TODO: Chamar send() com a mensagem em cada notificação
// Imprimir cada resultado em sua própria linha nesta ordem:
// 1. Notificação regular
// 2. Notificação urgente
// 3. Notificação registrada
?>Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave $thisMétodosPropriedadesConstrutor (__construct)Destrutor (__destruct)Recapitulação - Calculadora Simples4Herança
Herança BásicaA Palavra-chave parent::Sobrescrita de MétodoA Palavra-chave finalClasses AbstratasRecapitulação - Hierarquia de Funcionários7Encapsulamento
Público, Protegido, PrivadoModificadores de Acesso em DetalhesGetters e SettersOcultação de InformaçãoPromoção de Construtor (8.0)Recapitulação - Sistema de Registro de Alunos10Conceitos Avançados de POO
Composição vs HerançaInjeção de DependênciaClasses AnônimasEnums (PHP 8.1)Fibers (PHP 8.1)Mergulho Profundo em Clonagem de ObjetosGeradores e Iteradores13Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Repository2Namespaces e Autoloading
Introdução a NamespacesA Palavra-chave usePadrão de Autoloading PSR-4Autoloader do ComposerRecapitulação - Projeto Organizado5Interfaces e Contratos
Introdução a InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesInterface vs Classe AbstrataType Hinting com InterfacesRecapitulação - Calculadora de Formas8Métodos Mágicos
Introdução aos Métodos Mágicos__toString e __debugInfo__get, __set, __isset, __unset__call e __callStatic__clone e Clonagem de Objetos__serialize e __unserializeRecapitulação - Coleção Personalizada11Sistema de Tipos e Tratamento de Erros
Declarações de TiposTipos AnuláveisTipos de União e InterseçãoClasses de ExceçãoHierarquia de Exceções PersonalizadasTry, Catch, FinallyRecapitulação - Validador de Formulário14Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses Livro e Usuário3Propriedades de Classe
Propriedades de Instância vs EstáticasConstantes em ClassesMétodos e Propriedades EstáticosPropriedades Privadas e ProtegidasPropriedades Readonly (PHP 8.1)Recapitulação - Gerenciador de Conta Bancária6Polimorfismo
Sobrescrita de Métodos RevisitadaPolimorfismo via InterfacesType Hinting e Union TypesLate Static BindingRecapitulação - Processador de Pagamentos9Traits
Introdução a TraitsUsando Múltiplos TraitsResolução de Conflitos de TraitsMétodos Abstratos em TraitsTraits vs Herança12Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy