Zum Inhalt springen

Websiteentwicklung: PHP: Traits

Aus Wikibooks

Traits

[Bearbeiten]

Ein Trait hat Ähnlichkeiten mit einer Klasse. Man kann diesen allerdings nicht instantiieren. Ein Trait wird benutzt um eine Menge an Methoden in mehreren voneinander unabhängigen Klassen zu benutzen.

Der Trait verhindert somit Probleme die entstehen können durch Mehrfachvererbung.

trait Hallo {
    public function sagHallo() {
        echo 'Hallo Welt!';
    }
}

class Klasse1 {
    use Hallo;
    public function sagMehr() {
        echo ' In Klasse 1';
    }
}

class Klasse2 {
    use Hallo;
    public function sagMehr() {
        echo ' In Klasse 2';
    }
}

$o = new Klasse1();
$o->sagHallo();
$o->sagMehr();
$u = new Klasse2();
$u->sagHallo();
$u->sagMehr();

Ausgabe:

Hallo Welt! In Klasse 1
Hallo Welt! In Klasse 2

Der Trait definiert eine Funktion die wir mit dem Keyword "use" in eine Klasse integrieren können. Der Trait ist in beliebig vielen Klassen einsetzbar und erlaubt so eine horizontale Wiederverwendung des Codes (engl. horizontal reuse).

Es können auch mehrere Traits in einer Klasse verwendet werden, dazu werden die Traits in der "use" Anweisung per Komma getrennt:

use Hallo, Welt;

Zu beachten in Verbindung mit Namespaces wäre: Der use Operator außerhalb von Klassen für Namespaces sieht seine Argumente immer als absolut an, der use Operator für Traits beachtet den vorherigen use Operator für Namespaces und ist somit relativ.

Die Methoden der aktuellen Klasse überschreiben die Methoden des Traits. Die Methoden des Traits überschreiben aber die Methoden, die die aktuelle Klasse von einer Vaterklasse geerbt hat.

Weitere Möglichkeiten mit use

[Bearbeiten]

Durch eine "use" Anweisung kann man ebenfalls die folgenden Dinge machen:

Konfliktauflösung

[Bearbeiten]
trait Foo {
    public function sayName() {
        echo 'Foo';
    }
}

trait Bar {
    public function sayName() {
        echo 'Bar';
    }
}

class Talker {
    use Foo, Bar {
        Foo::sayName insteadof Bar;
        Bar::sayName as sayBarName;
    }
}

Hier haben beide Traits eine Methode mit gleichem Namen, um beide Traits zu implementieren, muss man sich nun eine dieser Methoden aussuchen mit dem Schlüsselwort "insteadof". Danach kann man allerdings der hier ausgeschlossenen Methode einen Alias geben mit dem Schlüsselwort "as". Im oberen Beispiel haben wir also nun 2 Methoden: sayName() ruft die Funktion im Trait Foo auf und sayBarName() ruft die Funktion sayName() im Trait Bar auf. Der Alias ist hier allerdings optional, wenn man ihn weglässt steht die Funktion aus dem Trait Bar einfach nicht zur Verfügung.

Veränderung der Sichtbarkeit von Methoden

[Bearbeiten]
trait Foo {
    public function Bar() {
        echo 'Hallo Welt!';
    }
}

class Klasse1 {
    use Foo { Bar as private }
}

class Klasse2 {
    use Foo {Bar as private FooBar }
}

Hier verändern wir die Sichtbarkeit der Methode Bar in Klasse 1 und setzen die Sichtbarkeit für unsere Klasse 1 auf private. In Klasse 2 geben wir der Funktion die ebenfalls auf private gesetzt wird noch ein Alias namens "FooBar".

Traits und Vererbung

[Bearbeiten]

Traits können auch das "use" Konstrukt benutzen um einen anderen Trait zu implementieren:

trait Hallo {
    public function sagHallo() {
        echo 'Hallo Welt!';
    }
}

trait Mehr {
    public function sagMehr() {
        echo ' Zweiter Trait';
    }
}

trait HalloMehr {
    use Hallo, Mehr;
}

class Klasse1 {
    use HalloMehr;
}

$o = new Klasse1();
$o->sagHallo();
$o->sagMehr();

Ausgabe:

Hallo Welt! Zweiter Trait

Weitere Möglichkeiten in Traits

[Bearbeiten]

Es gibt noch einige weitere Möglichkeiten in Traits: Die Schlüsselwörter abstract und static werden unterstützt und funktionieren genauso wie in normalen Klassen, bis auf die Ausnahme, dass jede Klasse die einen statischen Member hat eine eigene Instanz hat davon. (Das heißt der statische Member ist an die Klasse die den Trait implementiert und nicht den Trait als solchen gebunden.)

Außerdem ist es auch möglich Eigenschaften in Traits zu benutzen:

trait FooBar {
    public $foo = "Bar";
}

Die Eigenschaften können dann von der Klasse die diesen Trait implementiert nicht mehr überschrieben werden.

PHP-Dokumentation

[Bearbeiten]

Folgender Abschnitt der PHP-Dokumentation wurde in diesem Kapitel behandelt: