Introducción a los Traits
Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy. Lección 51 de 91.
PHP solo admite herencia simple: una clase puede extender una única clase principal. Pero ¿qué ocurre si necesitas compartir funcionalidad entre varias clases no relacionadas? Aquí es donde entran en juego los traits.
Un trait es un mecanismo para reutilizar código que te permite definir métodos y propiedades que se pueden insertar en varias clases. Piensa en los traits como copiar y pegar a nivel del lenguaje: el código de un trait pasa a formar parte de la clase que lo utiliza.
<?php
trait Timestampable {
private string $createdAt;
public function setCreatedAt(): void {
$this->createdAt = date('Y-m-d H:i:s');
}
public function getCreatedAt(): string {
return $this->createdAt;
}
}
class Article {
use Timestampable;
public function __construct(public string $title) {
$this->setCreatedAt();
}
}
$article = new Article("PHP Traits");
echo $article->getCreatedAt();
La palabra clave use dentro de una clase importa los miembros del trait. Ahora Article tiene acceso a setCreatedAt() y getCreatedAt() como si estuvieran definidos directamente en la clase.
El mismo trait se puede utilizar en clases completamente no relacionadas: una clase Comment, una clase User o cualquier otra clase que necesite funcionalidad de marcas de tiempo. Esto resuelve la limitación de la herencia única al permitir compartir código horizontalmente en toda la jerarquía de clases.
Desafío
FácilConstruyamos un sistema sencillo de saludos que demuestre cómo los traits permiten compartir funcionalidad entre clases no relacionadas. Crearás un trait que proporciona una capacidad de saludo y luego lo usarás en dos clases completamente diferentes.
Organizarás tu código en tres archivos:
Greetable.php: Crea un trait llamadoGreetableque proporcione funcionalidad de saludo. El trait debe tener:- Una propiedad privada
$greeting(cadena) - Un método
setGreeting(string $greeting)que almacene el mensaje de saludo - Un método
greet()que devuelva el mensaje de saludo
- Una propiedad privada
Person.php: Crea una clasePersonque use el traitGreetable. Incluye el archivo del trait y usa la promoción del constructor para definir una propiedad pública$name. En el constructor, llama asetGreeting()para establecer el saludo como"Hello, I'm [name]".Robot.php: Crea una claseRobotque también use el traitGreetable. Incluye el archivo del trait y usa la promoción del constructor para definir una propiedad pública$model. En el constructor, llama asetGreeting()para establecer el saludo como"Beep boop, I am model [model]".
En main.php, incluye ambos archivos de clase. Recibirás dos entradas: el nombre de una persona y el número de modelo de un robot. Crea instancias de ambas clases e imprime sus saludos en líneas separadas.
Esto demuestra el poder de los traits: Person y Robot son clases completamente no relacionadas que no tienen un padre común; aun así, ambas obtienen la misma funcionalidad de saludo mediante el trait. Cada clase personaliza la forma en que utiliza esa funcionalidad según sus propias necesidades.
Pruébalo tú mismo
<?php
require_once 'Person.php';
require_once 'Robot.php';
// Leer entrada
$name = trim(fgets(STDIN));
$model = trim(fgets(STDIN));
// TODO: Crea una instancia de Person con el nombre dado
// TODO: Crea una instancia de Robot con el modelo dado
// TODO: Imprime el saludo de Person
// TODO: Imprime el saludo de Robot (en una nueva línea)
?>Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de la POO
Archivos externosIntroducción a la POOClases frente a objetosLa palabra clave $thisMétodosPropiedadesConstructor (__construct)Destructor (__destruct)Repaso: calculadora simple4Herencia
Herencia básicaLa palabra clave parent::Sobrescritura de métodosLa palabra clave finalClases abstractasRepaso - Jerarquía de empleados7Encapsulación
Público, protegido, privadoModificadores de acceso en profundidadGetters y settersOcultación de la informaciónPromoción del constructor (8.0)Repaso: sistema de registros de estudiantes10Conceptos avanzados de OOP
Composición vs. herenciaInyección de dependenciasClases anónimasEnums (PHP 8.1)Fibras (PHP 8.1)Análisis profundo de la clonación de objetosGeneradores e iteradores13Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Repository2Namespaces y carga automática
Introducción a los NamespacesLa palabra clave useEstándar de carga automática PSR-4Autoloader de ComposerRepaso: proyecto organizado5Interfaces y contratos
Introducción a las interfacesImplementación de interfacesImplementación de múltiples interfacesInterfaces vs. clase abstractaTipado con interfacesRepaso - Calculadora de formas8Métodos mágicos
Introducción a los métodos mágicos__toString y __debugInfo__get, __set, __isset, __unset__call y __callStatic__clone y clonación de objetos__serialize y __unserializeRepaso: colección personalizada3Propiedades de clase
Propiedades de instancia vs. estáticasConstantes en clasesMétodos y propiedades estáticosPropiedades privadas y protegidasPropiedades de solo lectura (PHP 8.1)Repaso: gestor de cuentas bancarias6Polimorfismo
Repaso de la sobrescritura de métodosPolimorfismo mediante interfacesAnotaciones de tipo y tipos uniónEnlace estático tardíoRepaso: procesador de pagos9Traits
Introducción a los TraitsUso de múltiples TraitsResolución de conflictos entre TraitsMétodos abstractos en TraitsTraits frente a la herencia12Patrones de diseño, parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón StrategyPractica por tu cuenta: Compilador de PHP online