domingo, 5 de junio de 2016

Traits en PHP


Buscando sobre traits en scala me encontré con que Php tambien tiene traits desde la versión 5.4.0

Los traits (rasgos) son un mecanismo de reutilización de código en lenguajes de herencia simple, como PHP. El objetivo de un trait es el de reducir las limitaciones propias de la herencia simple permitiendo que los desarrolladores reutilicen a voluntad conjuntos de métodos sobre varias clases independientes y pertenecientes a clases jerárquicas distintas. La semántica a la hora combinar Traits y clases se define de tal manera que reduzca su complejidad y se eviten los problemas típicos asociados a la herencia múltiple y a los Mixins.

Un Trait es similar 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.

Para los que vienen de Java es como las interfaces con métodos por defecto de Java 8.

Veamos un ejemplo:

<?php
trait ezcReflectionReturnInfo {
    function getReturnType() { /*1*/ }
    function getReturnDescription() { /*2*/ }
}

class ezcReflectionMethod extends ReflectionMethod {
    use ezcReflectionReturnInfo;
    /* ... */
}

class ezcReflectionFunction extends ReflectionFunction {
    use ezcReflectionReturnInfo;
    /* ... */
}
?>

Los miembros heredados de una clase base se sobrescriben cuando se inserta otro miembro homónimo desde un Trait. De acuerdo con el orden de precedencia, los miembros de la clase actual sobrescriben los métodos del Trait, que a su vez sobrescribe los métodos heredados.

Se sobrescribe un miembro de la clase base con el método insertado en MiHolaMundo a partir del Trait DecirMundo. El comportamiento es el mismo para los métodos definidos en la clase MiHolaMundo. Según el orden de precedencia los métodos de la clase actual sobrescriben los métodos del Trait, a la vez que el Trait sobrescribe los métodos de la clase base.

Veamos un ejemplo:

<?php
class Base {
    public function decirHola() {
        echo '¡Hola ';
    }
}

trait DecirMundo {
    public function decirHola() {
        parent::decirHola();
        echo 'Mundo!';
    }
}

class MiHolaMundo extends Base {
    use DecirMundo;
}

$o = new MiHolaMundo();
$o->decirHola();
?>

y el resultado va a ser:

¡Hola Mundo!

Se pueden insertar múltiples Traits en una clase, mediante una lista separada por comas en la sentencia use.

<?php
trait Hola {
    public function decirHola() {
        echo 'Hola ';
    }
}

trait Mundo {
    public function decirMundo() {
        echo 'Mundo';
    }
}

class MiHolaMundo {
    use Hola, Mundo;
    public function decirAdmiración() {
        echo '!';
    }
}

$o = new MiHolaMundo();
$o->decirHola();
$o->decirMundo();
$o->decirAdmiración();
?>

y el resultado sería:

Hola Mundo!

Hace mucho que no hago algo en PHP, pero se ve a las claras como evoluciono y evoluciona para bien.

Dejo la fuente:
http://php.net/manual/es/language.oop5.traits.php