
En PHP 5.4 se introdujo en el lenguaje una construcción nueva llamada «trait». Con los traits, las clases de PHP pasaron a poder heredar métodos y propiedades de varias fuentes. Una respuesta directa al problema de la herencia simple.
Aquí tienes un ejemplo:
<?php
trait PersonTrait
{
}Como ves, un trait se parece mucho a una clase. La diferencia es que se declara con la palabra clave trait. Existe una convención de nombres al crear un trait que consiste en añadir el sufijo Trait, te recomiendo seguirla para mantener una estructura clara.
A diferencia de una clase, conviene recordar que un trait no se puede extender ni implementar. Tampoco se puede instanciar. Su único objetivo es enriquecer nuestras clases, no sustituirlas.
Los traits pueden tener métodos, igual que las clases. Imaginemos una clase Person.
<?php
abstract class Person
{
}Nuestra clase Person es una clase abstracta. Es decir, está pensada para que la extiendan otras clases que representan personas.
Supongamos que queremos añadir un método fireball(). Por ejemplo, para lanzar bolas de fuego y hacer magia. Podríamos escribir algo así.
<?php
abstract class Person
{
public function fireball()
{
echo 'This Person send a fireball';
}
}El problema es que no quieres que todo el mundo pueda lanzar una bola de fuego, y ahí es donde entran los traits.
Los traits son perfectos para añadir métodos a un objeto. Queremos dárselo a los humanos que tienen poderes mágicos, así que lo que buscamos es un PowerTrait
<?php
trait PowerTrait
{
public function fireball()
{
echo 'This person send a fireball.';
}
}Hemos movido el método fireball() al trait. No hay ninguna otra diferencia. Eso significa que también podemos quitar el método de Person, así.
<?php
abstract class Animal
{
}Creemos una clase Elfe que herede de Person.
class Elfe extends Person
{
private $name="Legolas"; // Sí, ya sé que Legolas no lanza bolas de fuego, pero es el único que se me venía a la cabeza...
}Ya tenemos la clase Elfe, aunque de momento esté vacía. Imaginemos que los elfos pueden lanzar hechizos: vamos a usar el trait PowerTrait
<?php
class Elfe extends Person
{
use PowerTrait;
private $name="Legolas";
}La palabra clave para añadir un trait a una clase es use, colocando la declaración use PowerTrait;
Probemos a usar el método heredado del trait.
<?php
// Crear un nuevo panda rojo.
$legolas = new Elfe;
// Acariciar al panda.
$legolas->fireball();De momento solo hemos usado un trait, pero se pueden usar tantos como hagan falta. Por ejemplo, esto es posible.
<?php
class Elfe extends Person
{
use PlayerTrait;
use PowerTrait;
use AttributTrait;
private $name="Legolas";
}Usa los traits para enriquecer la funcionalidad de tus clases. Eso sí, solo puedes usarlos en PHP >= 5.4, tenlo presente.
Prioridad
Quizá te estés preguntando lo siguiente. ¿Qué ocurre si extendemos una clase y usamos un trait que tiene un método con el mismo nombre?
Míralo con este ejemplo:
<?php
trait TestTrait
{
public function test()
{
echo 'Méthode d\'un trait';
}
}
class TestClass
{
public function test()
{
echo 'Méthode d\'une classe';
}
}Aquí tenemos un TestTrait y una TestClass. Los dos tienen un método test() que indica desde dónde se llama al método.
Toca probar:
<?php
class Testing extends TestClass
{
use TestTrait;
}
$test = new Testing;
$test->test();Hemos creado una clase que extiende TestClass y usa TestTrait. Al llamar al método compartido test() podemos ver cuál tiene prioridad en la salida. Vamos a comprobarlo.
Méthode d'un traitvemos que el método del trait tiene prioridad sobre el método de la clase heredada.
Eso significa que podemos usar traits para sustituir la funcionalidad heredada de las clases abstractas. Es útil entenderlo si vas a usar traits, y también conviene saber cuándo usar un trait en PHP, para responder a esa pregunta te invito a leer otro artículo sobre el tema.


