Menu
Coddy logo textTech

Resolución de conflictos entre Traits

Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy. Lección 53 de 91.

Cuando dos traits definen métodos con el mismo nombre, PHP produce un error fatal. Debes indicar explícitamente a PHP cómo gestionar este conflicto mediante los operadores insteadof y as.

<?php
trait FileLogger {
    public function log(string $message): void {
        echo "File: $message";
    }
}

trait DatabaseLogger {
    public function log(string $message): void {
        echo "DB: $message";
    }
}

class Application {
    use FileLogger, DatabaseLogger {
        FileLogger::log insteadof DatabaseLogger;
        DatabaseLogger::log as logToDatabase;
    }
}

$app = new Application();
$app->log("Error occurred");
$app->logToDatabase("Error occurred");

Salida:

File: Error occurred
DB: Error occurred

El operador insteadof elige qué método del trait usar cuando hay un conflicto. En este ejemplo, FileLogger::log gana y se convierte en el método log() predeterminado. El operador as crea un alias, lo que te permite acceder al método del otro trait con un nombre diferente.

También puedes usar as para cambiar la visibilidad de un método:

<?php
trait Greeting {
    public function sayHello(): void {
        echo "Hello!";
    }
}

class Person {
    use Greeting {
        sayHello as private;
    }
}

Esto hace que sayHello() sea privada dentro de la clase Person, aunque sea pública en el trait. La resolución de conflictos te proporciona un control detallado sobre cómo se integran los métodos del trait en tus clases.

challenge icon

Desafío

Fácil

Construyamos un sistema de notificaciones en el que distintos canales puedan enviar mensajes, pero necesitamos resolver los conflictos cuando varios traits proporcionan el mismo nombre de método.

Organizarás tu código en cuatro archivos:

  • EmailNotifier.php: Crea un trait llamado EmailNotifier con un método notify(string $message) que devuelve "Email: [message]".
  • SmsNotifier.php: Crea un trait llamado SmsNotifier con un método notify(string $message) que devuelve "SMS: [message]".
  • AlertService.php: Crea una clase AlertService que use ambos traits. Como ambos traits tienen un método notify(), tendrás que resolver este conflicto:
    • Usa EmailNotifier::notify como método notify() predeterminado
    • Crea un alias notifyBySms para el método SmsNotifier::notify
    Añade también un método notifyAll(string $message) que llame a ambos métodos de notificación y los devuelva combinados en líneas separadas.
  • main.php: Incluye todos los archivos necesarios y crea una instancia de AlertService. Recibirás una entrada: una cadena de mensaje. Imprime tres líneas:
    • El resultado de llamar a notify() con el mensaje
    • El resultado de llamar a notifyBySms() con el mensaje
    • El resultado de llamar a notifyAll() con el mensaje

Esto demuestra cómo insteadof resuelve qué método de trait prevalece cuando existe un conflicto de nombres, mientras que as te permite conservar el acceso al método del otro trait con un nombre diferente.

Pruébalo tú mismo

<?php
require_once 'AlertService.php';

// Leer entrada
$message = trim(fgets(STDIN));

// TODO: Crea una instancia de AlertService

// TODO: Imprime el resultado de llamar a notify() con el mensaje

// TODO: Imprime el resultado de llamar a notifyBySms() con el mensaje

// TODO: Imprime el resultado de llamar a notifyAll() con el mensaje
?>
quiz iconPonte a prueba

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

Practica por tu cuenta: Compilador de PHP online