Menu
Coddy logo textTech

Tratti vs ereditarietà

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

Ora che hai capito come funzionano i trait, chiariamo quando usare i trait invece dell'ereditarietà. Entrambi consentono di riutilizzare il codice, ma hanno scopi diversi e caratteristiche distinte.

L'ereditarietà stabilisce una relazione «è-un». Una classe Dog che estende Animal significa che un cane è un animale. La classe figlia eredita l'identità della classe genitore e può essere utilizzata ovunque sia previsto il tipo genitore.

I trait forniscono una funzionalità «has-a». Quando una classe usa un trait Loggable, ha funzionalità di logging, ma non diventa un logger. I trait aggiungono comportamento senza cambiare ciò che la classe è fondamentalmente.

<?php
// Ereditarietà: Dog È un Animal
class Animal {
    public function breathe(): void {
        echo "Breathing";
    }
}

class Dog extends Animal {
    public function bark(): void {
        echo "Woof!";
    }
}

// Trait: Dog HA la capacità di registrare i log
trait Loggable {
    public function log(string $msg): void {
        echo "Log: $msg";
    }
}

class Cat extends Animal {
    use Loggable;
}

Differenze principali da ricordare:

AspettoEreditarietàTrait
Relazioneè-unha-una-funzionalità
LimiteUn solo genitoreSono consentiti più trait
Controllo del tipoFunziona con instanceofNessuna identità di tipo
Ideale perRelazioni gerarchicheComportamenti condivisi tra classi non correlate

Usa l’ereditarietà quando le classi condividono un’identità comune. Usa i trait quando classi non correlate hanno bisogno delle stesse funzionalità senza appartenere allo stesso albero genealogico.

challenge icon

Sfida

Facile

Costruiamo un sistema di veicoli che mostri quando usare l'ereditarietà anziché i trait. Creerai una gerarchia di veicoli che condividono un'identità comune tramite l'ereditarietà, aggiungendo al contempo funzionalità trasversali tramite i trait.

Organizzerai il codice in quattro file:

  • Trackable.php: crea un trait chiamato Trackable che fornisca la funzionalità di tracciamento GPS. Il trait dovrebbe avere:
    • Una proprietà privata $location (stringa)
    • Un metodo setLocation(string $location) che memorizzi la posizione corrente
    • Un metodo getLocation() che restituisca "Location: [location]"
    Questo trait rappresenta una capacità «ha»: qualsiasi veicolo può avere il tracciamento, ma avere il tracciamento non rende qualcosa un veicolo.
  • Vehicle.php: crea una classe base Vehicle che stabilisca la relazione «è un». Includi il file del trait. Usa la promozione del costruttore per definire una proprietà $brand protetta. Aggiungi un metodo describe() che restituisca "Vehicle: [brand]". Questa classe dovrebbe usare il trait Trackable, poiché tutti i veicoli della nostra flotta avranno il GPS.
  • Car.php: crea una classe Car che estenda Vehicle. Includi il file Vehicle. Usa la promozione del costruttore per accettare la marca e una proprietà privata $doors (intero). Chiama il costruttore del genitore passando la marca. Sovrascrivi il metodo describe() in modo che restituisca "Car: [brand] with [doors] doors".
  • main.php: includi il file Car. Riceverai tre input: il nome di una marca, il numero di porte e una stringa con la posizione. Crea un'istanza di Car, imposta la sua posizione, quindi stampa due righe:
    • Il risultato della chiamata a describe()
    • Il risultato della chiamata a getLocation()

Nota come funzionano insieme l'ereditarietà e i trait: Car è un Vehicle (l'ereditarietà stabilisce l'identità), mentre Vehicle ha la funzionalità di tracciamento (il trait aggiunge comportamento). Potresti usare instanceof Vehicle per verificare se qualcosa è un veicolo, ma non esiste un tipo «Trackable» da usare per il controllo: questa è la differenza fondamentale tra i due approcci.

Provalo tu

<?php
// File principale - crea e verifica l'istanza di Car

// TODO: Includi il file Car.php

// Leggi i dati di input
$brand = trim(fgets(STDIN));
$doors = intval(trim(fgets(STDIN)));
$location = trim(fgets(STDIN));

// TODO: Crea un'istanza di Car con brand e doors

// TODO: Imposta la posizione dell'auto

// TODO: Stampa il risultato di describe()

// TODO: Stampa il risultato di getLocation()
?>
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