Implementando Interfaces
Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy — lição 28 de 91.
Agora que você entende o que são interfaces, vamos ver como implementá-las na prática. Uma classe implementa uma interface usando a palavra-chave implements e deve fornecer implementações concretas para todos os métodos declarados nessa interface.
<?php
interface Printable {
public function print();
}
class Document implements Printable {
private $content;
public function __construct($content) {
$this->content = $content;
}
public function print() {
return "Printing: " . $this->content;
}
}
$doc = new Document("Hello World");
echo $doc->print();
Saída:
Printing: Hello WorldA classe Document implementa Printable fornecendo sua própria versão do método print(). Se você esquecer de implementar um método obrigatório, o PHP lançará um erro fatal.
Diferentes classes podem implementar a mesma interface de sua própria maneira:
<?php
class Invoice implements Printable {
private $amount;
public function __construct($amount) {
$this->amount = $amount;
}
public function print() {
return "Invoice Total: $" . $this->amount;
}
}
$invoice = new Invoice(150);
echo $invoice->print();
Saída:
Invoice Total: $150Tanto Document quanto Invoice cumprem o contrato Printable, mas cada um lida com a impressão de forma diferente com base em seu propósito.
Ponto Chave: Use implements para conectar uma classe a uma interface, então defina todos os métodos obrigatórios. Cada classe implementadora fornece sua própria lógica enquanto garante que as mesmas assinaturas de método existam.
Desafio
FácilVamos construir um sistema de mensagens que demonstra como diferentes classes podem implementar a mesma interface de suas próprias maneiras únicas.
Você criará três arquivos que trabalham juntos para lidar com diferentes tipos de mensagens:
Messageable.php— Defina a interfaceMessageablecom duas assinaturas de método:compose($content)edeliver(). Esta interface estabelece o contrato que todos os tipos de mensagens devem seguir.Email.php— Crie uma classeEmailque implementaMessageable. Inclua o arquivo da interface no topo. A classe deve ter uma propriedade privada$recipiente uma propriedade privada$body. O construtor aceita o endereço do destinatário. Implementecompose($content)para armazenar o conteúdo em$bodye retornar"Email composed". Implementedeliver()para retornar"Email to [recipient]: [body]".SMS.php— Crie uma classeSMSque também implementaMessageable. Inclua o arquivo da interface no topo. A classe deve ter uma propriedade privada$phoneNumbere uma propriedade privada$text. O construtor aceita o número de telefone. Implementecompose($content)para armazenar o conteúdo em$texte retornar"SMS composed". Implementedeliver()para retornar"SMS to [phoneNumber]: [text]".
Em main.php, inclua os arquivos Email e SMS. Você receberá três entradas: um endereço de e-mail, um número de telefone e o conteúdo de uma mensagem. Crie um objeto Email com o endereço de e-mail e um objeto SMS com o número de telefone. Chame compose() com o conteúdo da mensagem em ambos os objetos, imprimindo cada resultado em sua própria linha. Em seguida, chame deliver() em ambos os objetos, imprimindo cada resultado em sua própria linha. A ordem deve ser: email compose, SMS compose, email deliver, SMS deliver.
Ambas as classes cumprem o mesmo contrato Messageable, mas cada uma lida com a composição e entrega de mensagens de acordo com seu próprio propósito — e-mails mostram o endereço do destinatário, enquanto mensagens SMS mostram o número de telefone.
Folha de consulta
Uma classe implementa uma interface usando a palavra-chave implements e deve fornecer implementações concretas para todos os métodos declarados nessa interface:
<?php
interface Printable {
public function print();
}
class Document implements Printable {
private $content;
public function __construct($content) {
$this->content = $content;
}
public function print() {
return "Printing: " . $this->content;
}
}
Múltiplas classes podem implementar a mesma interface, cada uma fornecendo sua própria implementação:
<?php
class Invoice implements Printable {
private $amount;
public function __construct($amount) {
$this->amount = $amount;
}
public function print() {
return "Invoice Total: $" . $this->amount;
}
}
Se uma classe falhar em implementar todos os métodos exigidos por uma interface, o PHP lançará um erro fatal.
Experimente você mesmo
<?php
require_once 'Email.php';
require_once 'SMS.php';
// Ler entradas
$emailAddress = trim(fgets(STDIN));
$phoneNumber = trim(fgets(STDIN));
$messageContent = trim(fgets(STDIN));
// TODO: Criar um objeto Email com o endereço de e-mail
// TODO: Criar um objeto SMS com o número de telefone
// TODO: Chamar compose() em ambos os objetos e imprimir os resultados
// Ordem: compose do e-mail, depois compose do SMS
// TODO: Chamar deliver() em ambos os objetos e imprimir os resultados
// Ordem: deliver do e-mail, depois deliver do SMS
?>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