Utilizzare più tratti
Fa parte della sezione Programmazione orientata agli oggetti del percorso PHP di Coddy. Lezione 52 di 91.
Un singolo trait è utile, ma il vero potere emerge quando combini più trait in una classe. PHP ti consente di includere tutti i trait di cui hai bisogno, fornendo alla tua classe capacità provenienti da diverse fonti contemporaneamente.
Per usare più trait, elencali semplicemente separati da virgole dopo la parola chiave use:
<?php
trait Timestampable {
public function getTimestamp(): string {
return date('Y-m-d H:i:s');
}
}
trait Identifiable {
private string $id;
public function generateId(): void {
$this->id = uniqid('id_');
}
public function getId(): string {
return $this->id;
}
}
class Post {
use Timestampable, Identifiable;
public function __construct(public string $title) {
$this->generateId();
}
}
$post = new Post("Hello World");
echo $post->getId() . " - " . $post->getTimestamp();
Output:
id_6789abc123 - 2024-01-15 10:30:00La classe Post ora dispone dei metodi di entrambi i trait. Ogni trait contribuisce con le proprie funzionalità: Timestampable fornisce metodi relativi al tempo, mentre Identifiable gestisce gli ID univoci. Questo approccio mantiene ogni trait concentrato su una singola responsabilità, rendendo il tuo codice più modulare e riutilizzabile.
Cosa succede quando due trait hanno metodi con lo stesso nome? È una situazione di conflitto che esploreremo nella prossima lezione.
Sfida
FacileCreiamo un sistema di gestione dei prodotti che combina più trait per fornire ai prodotti funzionalità sia di determinazione dei prezzi sia di gestione delle scorte. Ogni trait si occuperà di una singola responsabilità e la tua classe prodotto acquisirà funzionalità da entrambi.
Organizzerai il codice in tre file:
Priceable.php: crea un trait chiamatoPriceableche gestisce la funzionalità di determinazione dei prezzi. Il trait dovrebbe avere:- Una proprietà privata
$price(float) - Un metodo
setPrice(float $price)che memorizza il prezzo - Un metodo
getPrice()che restituisce il prezzo - Un metodo
getFormattedPrice()che restituisce il prezzo formattato come"$[price]"con 2 cifre decimali
- Una proprietà privata
Stockable.php: crea un trait chiamatoStockableche gestisce le scorte. Il trait dovrebbe avere:- Una proprietà privata
$stock(intero) - Un metodo
setStock(int $quantity)che memorizza la quantità in magazzino - Un metodo
getStock()che restituisce le scorte attuali - Un metodo
isInStock()che restituiscetruese le scorte sono maggiori di 0,falsealtrimenti
- Una proprietà privata
main.php: includi entrambi i file dei trait e crea una classeProductche usa entrambi i traitPriceableeStockable. Usa la promozione del costruttore per definire una proprietà pubblica$name. Il costruttore dovrebbe anche accettare un prezzo e una quantità in magazzino, usando i metodi dei trait per impostarli.Riceverai tre input: un nome di prodotto, un prezzo e una quantità in magazzino. Crea un prodotto con questi valori e stampa quattro righe:
- Il nome del prodotto
- Il prezzo formattato (usando
getFormattedPrice()) - La quantità in magazzino
"Available"se disponibile, oppure"Out of stock"se non lo è
Questo dimostra come più trait possano lavorare insieme. La tua classe Product acquisisce funzionalità di determinazione dei prezzi da un trait e di gestione delle scorte da un altro, mantenendo ciascuna responsabilità ben separata e combinandole in un prodotto completo di tutte le funzionalità.
Provalo tu
<?php
require_once 'Priceable.php';
require_once 'Stockable.php';
// TODO: Crea una classe Product che utilizzi entrambi i trait Priceable e Stockable
// Usa la promozione dei parametri del costruttore per la proprietà pubblica $name
// Il costruttore deve accettare name, price e stock e usare i metodi dei trait per impostare price e stock
class Product {
// TODO: Usa i trait qui
// TODO: Implementa il costruttore con la promozione dei parametri per $name
// e imposta price e stock usando i metodi dei trait
}
// Leggi l'input
$name = trim(fgets(STDIN));
$price = floatval(trim(fgets(STDIN)));
$stock = intval(trim(fgets(STDIN)));
// TODO: Crea un'istanza di Product con i valori di input
// TODO: Stampa il nome del prodotto
// TODO: Stampa il prezzo formattato usando getFormattedPrice()
// TODO: Stampa la quantità disponibile
// TODO: Stampa "Available" se il prodotto è disponibile, altrimenti "Out of stock"
?>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
1Fondamenti della programmazione orientata agli oggetti
File esterniIntroduzione alla programmazione orientata agli oggettiClassi e oggettiLa parola chiave $thisMetodiProprietàCostruttore (__construct)Distruttore (__destruct)Riepilogo - Calcolatrice semplice4Ereditarietà
Ereditarietà di baseLa parola chiave parent::Sovrascrittura dei metodiLa parola chiave finalClassi astratteRiepilogo - Gerarchia dei dipendenti7Incapsulamento
Pubblico, Protetto, PrivatoApprofondimento sui modificatori di accessoGetter e SetterOccultamento delle informazioniPromozione dei parametri del costruttore (8.0)Riepilogo - Sistema di gestione dei registri degli studenti10Concetti avanzati di programmazione a oggetti
Composizione vs ereditarietàDependency InjectionClassi anonimeEnumerazioni (PHP 8.1)Fibers (PHP 8.1)Approfondimento sulla clonazione degli oggettiGeneratori e iteratori13Modelli di progettazione, parte 2
Modello CommandModello AdapterModello DecoratorModello Template MethodModello StateModello CompositeModello Repository2Namespace e autoloading
Introduzione ai namespaceLa keyword useStandard di autoloading PSR-4Autoloader di ComposerRiepilogo - Progetto organizzato5Interfacce e contratti
Introduzione alle interfacceImplementare le interfacceImplementare più interfacceInterfaccia vs classe astrattaType hinting con le interfacceRiepilogo - Calcolatore di forme8Metodi magici
Introduzione ai metodi magici__toString e __debugInfo__get, __set, __isset, __unset__call e __callStatic__clone e clonazione degli oggetti__serialize e __unserializeRiepilogo - Collezione personalizzata11Sistema dei tipi e gestione degli errori
Dichiarazioni di tipoTipi nullableTipi unione e intersezioneClassi di eccezioneGerarchia di eccezioni personalizzataTry, Catch, FinallyRiepilogo - Validatore di moduli14Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente3Proprietà delle classi
Proprietà di istanza e staticheCostanti nelle classiMetodi e proprietà staticiProprietà private e protectedProprietà readonly (PHP 8.1)Riepilogo - Gestore di conti bancari6Polimorfismo
Ridefinizione dei metodi, ripresaPolimorfismo tramite interfacceSuggerimenti sui tipi e tipi UnionBinding statico tardivoRiepilogo - Processore di pagamenti9Tratti
Introduzione ai trattiUtilizzare più trattiRisoluzione dei conflitti tra trattiMetodi astratti nei trattiTratti vs ereditarietà12Design pattern - Parte 1
Introduzione ai design patternPattern SingletonPattern FactoryPattern ObserverPattern StrategyEsercitati da solo: Compilatore PHP online