Fácil PHP
Trait de saudação
Enunciado
Crie uma trait Saudacao com o método dizerOla() que retorna "Olá, " . $this->nome. Depois, crie a classe Pessoa que usa a trait e tem a propriedade $nome definida no construtor. Instancie Pessoa('Maria') e imprima o retorno de dizerOla().
Requisitos
- A trait
Saudacaodeve ter o métododizerOla(). - A classe
Pessoadeve usar a trait comuse Saudacao;. - A classe
Pessoadeve ter propriedade$nomeacessível pelo método da trait. - A saída deve ser exatamente
Olá, Maria.
Código inicial
<?php
// Defina a trait Saudacao e a classe Pessoa
$p = new Pessoa('Maria');
echo $p->dizerOla();
Saída esperada
Olá, Maria
Ver dica
Dentro da trait, $this se refere à instância da classe que a usa. Então você pode acessar $this->nome diretamente.
Mostrar solução
<?php
// Trait com o método de saudação
trait Saudacao {
public function dizerOla(): string {
return "Olá, " . $this->nome;
}
}
// Classe que usa a trait
class Pessoa {
use Saudacao;
public function __construct(public string $nome) {}
}
$p = new Pessoa('Maria');
echo $p->dizerOla();
Passo a passo
- Declaramos a trait
Saudacaocomtrait Saudacao { ... }. - Dentro dela, o método
dizerOla()retorna a concatenação de"Olá, "com$this->nome. O$thisserá a instância da classe que usar a trait. - A classe
Pessoausa a trait comuse Saudacao;. - O construtor promovido define a propriedade pública
$nome. - Criamos
$p = new Pessoa('Maria')e chamamosdizerOla(), que acessa$this->nome(Maria). - O
echoimprime o resultado.
Por que funciona
A trait injeta o método dizerOla() na classe Pessoa como se ele tivesse sido escrito ali. Como $this aponta para o objeto Pessoa, o método consegue acessar a propriedade $nome definida na classe. Isso demonstra o reuso horizontal: a trait não precisa saber qual classe a usará, apenas que ela terá a propriedade esperada.
Erros comuns
- Esquecer o
use Saudacao;dentro da classe:$p->dizerOla()gera erro fatal "Call to undefined method". - Declarar a propriedade
$nomedentro da trait em vez da classe: embora possível, foge do propósito e pode causar conflitos. Prefira definir na classe. - Usar
$this->nomesem garantir que a propriedade exista: se a classe não tiver$nome, ocorre aviso de propriedade indefinida.
Outra forma de resolver
Usar um método abstrato na trait para forçar a classe a fornecer o nome:
trait Saudacao {
abstract public function getNome(): string;
public function dizerOla(): string {
return "Olá, " . $this->getNome();
}
}
Isso é preferível quando a trait precisa de um contrato claro em vez de acessar propriedades diretamente.
Saída esperada
Olá, Maria