Menu
Coddy logo textTech

Verwendung mehrerer Traits

Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy — Lektion 52 von 91.

Ein einzelnes Trait ist nützlich, aber die wahre Stärke zeigt sich, wenn man mehrere Traits in einer Klasse kombiniert. PHP ermöglicht es Ihnen, so viele Traits einzubinden, wie Sie benötigen, wodurch Ihre Klasse Funktionen aus mehreren Quellen gleichzeitig erhält.

Um mehrere Traits zu verwenden, listen Sie diese einfach durch Kommas getrennt nach dem use-Schlüsselwort auf:

<?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();

Ausgabe:

id_6789abc123 - 2024-01-15 10:30:00

Die Klasse Post verfügt nun über Methoden aus beiden Traits. Jeder Trait trägt seine eigene Funktionalität bei – Timestampable stellt zeitbezogene Methoden bereit, während Identifiable eindeutige IDs verarbeitet. Dieser Ansatz sorgt dafür, dass jeder Trait auf eine einzige Verantwortlichkeit konzentriert bleibt, was Ihren Code modularer und wiederverwendbarer macht.

Was passiert, wenn zwei Traits Methoden mit demselben Namen haben? Das ist eine Konfliktsituation, die wir in der nächsten Lektion untersuchen werden.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Produktmanagementsystem aufbauen, das mehrere Traits kombiniert, um Produkten sowohl Preis- als auch Bestandsfunktionen zu verleihen. Jeder Trait wird eine einzelne Aufgabe übernehmen, und Ihre Produktklasse wird die Funktionalität von beiden erhalten.

Sie werden Ihren Code über drei Dateien organisieren:

  • Priceable.php — Erstellen Sie einen Trait namens Priceable, der die Preisfunktionalität verwaltet. Der Trait sollte Folgendes enthalten:
    • Eine private Eigenschaft $price (float)
    • Eine Methode setPrice(float $price), die den Preis speichert
    • Eine Methode getPrice(), die den Preis zurückgibt
    • Eine Methode getFormattedPrice(), die den Preis formatiert als "$[price]" mit 2 Dezimalstellen zurückgibt
  • Stockable.php — Erstellen Sie einen Trait namens Stockable, der den Bestand verwaltet. Der Trait sollte Folgendes enthalten:
    • Eine private Eigenschaft $stock (integer)
    • Eine Methode setStock(int $quantity), die die Bestandsmenge speichert
    • Eine Methode getStock(), die den aktuellen Bestand zurückgibt
    • Eine Methode isInStock(), die true zurückgibt, wenn der Bestand größer als 0 ist, andernfalls false
  • main.php — Binden Sie beide Trait-Dateien ein und erstellen Sie eine Product-Klasse, die sowohl den Priceable- als auch den Stockable-Trait verwendet. Nutzen Sie Constructor Promotion, um eine öffentliche $name-Eigenschaft zu definieren. Der Konstruktor sollte außerdem einen Preis und eine Bestandsmenge akzeptieren und die Trait-Methoden verwenden, um diese zu setzen.

    Sie erhalten drei Eingaben: einen Produktnamen, einen Preis und eine Bestandsmenge. Erstellen Sie ein Produkt mit diesen Werten und geben Sie vier Zeilen aus:

    • Den Produktnamen
    • Den formatierten Preis (unter Verwendung von getFormattedPrice())
    • Die Bestandsmenge
    • "Available", wenn auf Lager, oder "Out of stock", wenn nicht

Dies zeigt, wie mehrere Traits zusammenarbeiten — Ihre Product-Klasse erhält Preisfunktionen von einem Trait und Bestandsverwaltung von einem anderen, wodurch jede Aufgabe sauber getrennt bleibt, während sie zu einem voll funktionsfähigen Produkt kombiniert werden.

Spickzettel

Um mehrere Traits in einer Klasse zu verwenden, listen Sie diese durch Kommas getrennt nach dem Schlüsselwort use auf:

<?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();
// Ausgabe: id_6789abc123 - 2024-01-15 10:30:00

Jeder Trait trägt seine eigene Funktionalität zur Klasse bei. Dieser Ansatz sorgt dafür, dass jeder Trait auf eine einzige Verantwortlichkeit fokussiert bleibt, was den Code modularer und wiederverwendbarer macht.

Probier es selbst

<?php
require_once 'Priceable.php';
require_once 'Stockable.php';

// TODO: Erstellen Sie eine Product-Klasse, die sowohl Priceable- als auch Stockable-Traits verwendet
// Verwenden Sie Constructor Promotion für die öffentliche Eigenschaft $name
// Der Konstruktor sollte Name, Preis und Bestand akzeptieren und Trait-Methoden verwenden, um Preis und Bestand festzulegen

class Product {
    // TODO: Verwenden Sie hier die Traits

    // TODO: Implementieren Sie den Konstruktor mit Constructor Promotion für $name
    // und legen Sie Preis und Bestand mithilfe von Trait-Methoden fest
}

// Eingabe lesen
$name = trim(fgets(STDIN));
$price = floatval(trim(fgets(STDIN)));
$stock = intval(trim(fgets(STDIN)));

// TODO: Erstellen Sie eine Product-Instanz mit den Eingabewerten

// TODO: Geben Sie den Produktnamen aus
// TODO: Geben Sie den formatierten Preis mit getFormattedPrice() aus
// TODO: Geben Sie die Bestandsmenge aus
// TODO: Geben Sie "Available" aus, wenn auf Lager, oder "Out of stock", wenn nicht
?>
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung