
No PHP 5.4 foi introduzida na linguagem uma construção nova chamada «trait». Com os traits, as classes de PHP passaram a poder herdar métodos e propriedades de várias fontes. Uma resposta direta ao problema da herança simples.
Eis um exemplo:
<?php
trait PersonTrait
{
}Como vês, um trait parece-se muito com uma classe. A diferença é que se declara com a palavra-chave trait. Existe uma convenção de nomes para os traits que consiste em acrescentar o sufixo Trait, segue-a quando criares os teus, para manter uma estrutura clara.
Ao contrário de uma classe, e convém não esquecer, um trait não se pode estender nem implementar. Também não se pode instanciar. O seu único objetivo é enriquecer as nossas classes, não substituí-las.
Os traits podem ter métodos, tal como as classes. Imaginemos uma classe Person.
<?php
abstract class Person
{
}A nossa classe Person é uma classe abstrata. Ou seja, foi pensada para ser estendida por outras classes que representam pessoas.
Suponhamos que queremos acrescentar um método fireball(). Por exemplo, para atirar bolas de fogo e fazer magia. Podíamos escrever algo assim.
<?php
abstract class Person
{
public function fireball()
{
echo 'This Person send a fireball';
}
}O problema é que não queres que toda a gente possa atirar uma bola de fogo, e é aqui que os traits entram em jogo.
Os traits são perfeitos para acrescentar métodos a um objeto. Queremos dá-lo aos humanos que têm poderes mágicos, por isso o que procuramos é um PowerTrait
<?php
trait PowerTrait
{
public function fireball()
{
echo 'This person send a fireball.';
}
}Movemos o método fireball() para o trait. Não há mais nenhuma diferença. Isso significa que também podemos retirar o método de Person, assim.
<?php
abstract class Animal
{
}Vamos criar uma classe Elfe que herda de Person.
class Elfe extends Person
{
private $name="Legolas"; // Sim, eu sei que o Legolas não atira bolas de fogo, mas foi o único que me veio à cabeça...
}Já temos a classe Elfe, ainda que por agora esteja vazia. Imaginemos que os elfos podem lançar feitiços: avancemos e usemos o trait PowerTrait
<?php
class Elfe extends Person
{
use PowerTrait;
private $name="Legolas";
}A palavra-chave para acrescentar um trait a uma classe é use, colocando a declaração use PowerTrait;
Vamos experimentar o método herdado do trait.
<?php
// Criar um novo panda-vermelho.
$legolas = new Elfe;
// Fazer festas ao panda.
$legolas->fireball();Por agora só usámos um trait, mas podes usar tantos quantos forem precisos. Por exemplo, isto é possível.
<?php
class Elfe extends Person
{
use PlayerTrait;
use PowerTrait;
use AttributTrait;
private $name="Legolas";
}Usa os traits para enriquecer a funcionalidade das tuas classes. Claro que só os podes usar em PHP >= 5.4, tem isso em conta.
Prioridade
Talvez estejas a fazer a pergunta seguinte. O que acontece se estendermos uma classe e usarmos um trait que tem um método com o mesmo nome?
Vê com este exemplo:
<?php
trait TestTrait
{
public function test()
{
echo 'Méthode d\'un trait';
}
}
class TestClass
{
public function test()
{
echo 'Méthode d\'une classe';
}
}Aqui temos um TestTrait e uma TestClass. Ambos têm um método test() que indica de onde vem a chamada.
Hora de testar:
<?php
class Testing extends TestClass
{
use TestTrait;
}
$test = new Testing;
$test->test();Criámos uma classe que estende a TestClass e usa o TestTrait. Ao chamar o método partilhado test(), vemos qual tem prioridade na saída. Vamos comprovar.
Méthode d'un traitvemos que o método do trait tem prioridade sobre o método da classe herdada.
Isso significa que podemos usar traits para substituir a funcionalidade herdada das classes abstratas. É útil perceber isto se pensas usar traits, e convém também saber quando usar um trait em PHP, para responder a essa pergunta, deixo-te outro artigo sobre o tema.


