Blog de Gonzalo

TRAITS

Los traits son un mecanismo para reutilizar código en un lenguaje que no soporta la herencia múltiple. Los traits reducen las limitaciones de la herencia simple, permitiendo a los desarrolladores reutilizar un conjunto de métodos en varias clases independientes de jerarquías. La semántica para combinar los traits y las clases es definida de tal manera que la complejidad es reducida y se evitan los problemas típicos asociados con la herencia múltiple.
En otras palabras se puede decir que un trait es igual a una clase, pero con el único objetivo de agrupar funcionalidades muy específicas y de una manera coherente. No se puede instanciar directamente un trait. Es por tanto un añadido a la herencia tradicional, y habilita la composición horizontal de comportamientos; es decir, permite combinar miembros de clases sin tener que usar herencia.
Voy a poner un ejemplo sencillo para entenderlo:


trait Hola{
    function saludo(){
        return 'hola';
    }
}
class UsarTraits {
    use Hola;
    function despedida(){
        return 'adios';
    }

}
$objTraits = new UsarTraits();
echo $objTraits->saludo();//Mostrará hola
Pero si la clase que invoca a un trait tiene un método con el mismo nombre lo sobreescribre:

trait Hola{
    function saludo(){
        return 'hola';
    }
}
class UsarTraits {
    use Hola;
    function saludo(){
        return 'hola figura';
    }
}
$objTraits = new UsarTraits();
echo $objTraits->saludo();//Mostrará hola figura
También se pueden usar un trait o más de uno dentro de otro trait.
Cuando dos traits han definido un método con el mismo nombre y luego se necesita utilizar ambos en la misma clase, surge un conflicto de nombres. Veámoslo con un ejemplo:

// Asumimos que los trait A y B tienen un método hello() definido
class Test {
use A, B {
B::hello insteadof A;
}
}
// La clase Test tendrá implementado el método "hello" del trait B

Este problema se soluciona usando el nuevo operador insteadof que excluye un método en favor del otro. Y si hubiera necesidad de utilizar las implementaciones de ambos métodos en la misma clase, se podría utilizar un alias:

class Test {
use A, B {
B::hello insteadof A;
A::hello as helloA;
}
}
// La clase Test tendrá implementado el método "hello" y "helloA"

As es un operador adicional que también podría para cambiar la visibilidad de un método y otros modificadores.

Compartir en twitter