Menu
Coddy logo textTech

Risoluzione dei conflitti tra tratti

Fa parte della sezione Programmazione orientata agli oggetti del percorso PHP di Coddy. Lezione 53 di 91.

Quando due trait definiscono metodi con lo stesso nome, PHP genera un errore fatale. Devi indicare esplicitamente a PHP come gestire questo conflitto usando gli operatori insteadof e 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");

Output:

File: Error occurred
DB: Error occurred

L'operatore insteadof sceglie il metodo di quale trait utilizzare in caso di conflitto. In questo esempio, FileLogger::log prevale e diventa il metodo log() predefinito. L'operatore as crea un alias, permettendoti di accedere al metodo dell'altro trait con un nome diverso.

Puoi anche usare as per modificare la visibilità di un metodo:

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

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

Questo rende sayHello() privato all'interno della classe Person, anche se è pubblico nel trait. La risoluzione dei conflitti ti offre un controllo dettagliato su come i metodi dei trait si integrano nelle tue classi.

challenge icon

Sfida

Facile

Creiamo un sistema di notifiche in cui diversi canali possono inviare messaggi, ma dobbiamo risolvere i conflitti quando più trait forniscono un metodo con lo stesso nome.

Organizzerai il codice in quattro file:

  • EmailNotifier.php: crea un trait chiamato EmailNotifier con un metodo notify(string $message) che restituisce "Email: [message]".
  • SmsNotifier.php: crea un trait chiamato SmsNotifier con un metodo notify(string $message) che restituisce "SMS: [message]".
  • AlertService.php: crea una classe AlertService che usa entrambi i trait. Poiché entrambi i trait hanno un metodo notify(), dovrai risolvere questo conflitto:
    • Usa EmailNotifier::notify come metodo predefinito notify()
    • Crea un alias notifyBySms per il metodo SmsNotifier::notify
    Aggiungi anche un metodo notifyAll(string $message) che chiama entrambi i metodi di notifica e li restituisce combinati su righe separate.
  • main.php: includi tutti i file necessari e crea un'istanza di AlertService. Riceverai un input: una stringa che rappresenta un messaggio. Stampa tre righe:
    • Il risultato della chiamata a notify() con il messaggio
    • Il risultato della chiamata a notifyBySms() con il messaggio
    • Il risultato della chiamata a notifyAll() con il messaggio

Questo mostra come insteadof risolve quale metodo del trait prevale in caso di conflitto tra nomi, mentre as ti permette di mantenere l'accesso al metodo dell'altro trait con un nome diverso.

Provalo tu

<?php
require_once 'AlertService.php';

// Leggi l'input
$message = trim(fgets(STDIN));

// TODO: Crea un'istanza di AlertService

// TODO: Stampa il risultato della chiamata a notify() con il messaggio

// TODO: Stampa il risultato della chiamata a notifyBySms() con il messaggio

// TODO: Stampa il risultato della chiamata a notifyAll() con il messaggio
?>
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore PHP online