Introdução a Traits
Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy — lição 51 de 91.
O PHP suporta apenas herança única - uma classe pode estender apenas uma classe pai. Mas e se você precisar compartilhar funcionalidades entre várias classes não relacionadas? É aqui que as traits entram.
Um trait é um mecanismo de reutilização de código que permite definir métodos e propriedades que podem ser inseridos em várias classes. Pense nos traits como um copiar e colar ao nível da linguagem - o código de um trait torna-se parte da classe que o utiliza.
<?php
trait Timestampable {
private string $createdAt;
public function setCreatedAt(): void {
$this->createdAt = date('Y-m-d H:i:s');
}
public function getCreatedAt(): string {
return $this->createdAt;
}
}
class Article {
use Timestampable;
public function __construct(public string $title) {
$this->setCreatedAt();
}
}
$article = new Article("PHP Traits");
echo $article->getCreatedAt();
A palavra-chave use dentro de uma classe importa os membros da trait. Agora Article tem acesso a setCreatedAt() e getCreatedAt() como se tivessem sido definidos diretamente na classe.
A mesma trait pode ser usada em classes completamente não relacionadas - uma classe Comment, uma classe User ou qualquer outra classe que precise de funcionalidade de timestamp. Isso resolve a limitação da herança única, permitindo o compartilhamento horizontal de código em toda a sua hierarquia de classes.
Desafio
FácilVamos construir um sistema de saudação simples que demonstra como as traits permitem compartilhar funcionalidades entre classes não relacionadas. Você criará uma trait que fornece uma capacidade de saudação e, em seguida, a usará em duas classes completamente diferentes.
Você organizará seu código em três arquivos:
Greetable.php— Crie uma trait chamadaGreetableque fornece funcionalidade de saudação. A trait deve ter:- Uma propriedade privada
$greeting(string) - Um método
setGreeting(string $greeting)que armazena a mensagem de saudação - Um método
greet()que retorna a mensagem de saudação
- Uma propriedade privada
Person.php— Crie uma classePersonque utiliza a traitGreetable. Inclua o arquivo da trait e use a promoção de construtor para definir uma propriedade pública$name. No construtor, chamesetGreeting()para definir a saudação como"Hello, I'm [name]".Robot.php— Crie uma classeRobotque também utiliza a traitGreetable. Inclua o arquivo da trait e use a promoção de construtor para definir uma propriedade pública$model. No construtor, chamesetGreeting()para definir a saudação como"Beep boop, I am model [model]".
Em main.php, inclua ambos os arquivos de classe. Você receberá duas entradas: o nome de uma pessoa e o número do modelo de um robô. Crie instâncias de ambas as classes e imprima suas saudações em linhas separadas.
Isso demonstra o poder das traits — Person e Robot são classes completamente não relacionadas, sem um pai compartilhado, mas ambas ganham a mesma funcionalidade de saudação por meio da trait. Cada classe personaliza como usa essa funcionalidade à sua maneira.
Folha de consulta
Uma trait é um mecanismo para reutilização de código que permite compartilhar métodos e propriedades entre várias classes não relacionadas, resolvendo a limitação de herança única do PHP.
Defina uma trait usando a palavra-chave trait:
<?php
trait Timestampable {
private string $createdAt;
public function setCreatedAt(): void {
$this->createdAt = date('Y-m-d H:i:s');
}
public function getCreatedAt(): string {
return $this->createdAt;
}
}
Use uma trait em uma classe com a palavra-chave use:
class Article {
use Timestampable;
public function __construct(public string $title) {
$this->setCreatedAt();
}
}
Os métodos e propriedades da trait tornam-se parte da classe como se tivessem sido definidos diretamente nela. Múltiplas classes não relacionadas podem usar a mesma trait para compartilhar funcionalidades horizontalmente em sua hierarquia de classes.
Experimente você mesmo
<?php
require_once 'Person.php';
require_once 'Robot.php';
// Ler a entrada
$name = trim(fgets(STDIN));
$model = trim(fgets(STDIN));
// TODO: Criar uma instância de Person com o nome fornecido
// TODO: Criar uma instância de Robot com o modelo fornecido
// TODO: Imprimir a saudação da Person
// TODO: Imprimir a saudação do Robot (em uma nova linha)
?>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