Websiteentwicklung: PHP: Interfaces

Interfaces

Bearbeiten

Schau dir einmal die folgende Klasse an:

class Versammlung {

  protected $sprecher = array();

  public function neuerSprecher($sprecher) {
    $this->sprecher[] = $sprecher;
  }

  public function alleStellenSichVor() {
    foreach ($this->sprecher as $sprecher) {
      $sprecher->sagHallo();
      echo '<br />';
    }
  }
}

Im Kapitel Methoden hatten wir dem Baum die Methode sagHallo gegeben. Somit können wir folgenden Code problemlos ausführen:

$baum = new Baum();
$versammlung = new Versammlung();
$versammlung->neuerSprecher($baum);
$versammlung->alleStellenSichVor();

Jetzt muss allerdings sichergestellt sein, dass alle Objekte, die wir an die Methode neuerSprecher übergeben, auch sprechen können, denn sonst würden wir Gefahr laufen, eine nicht existierende Methode aufzurufen. Bislang hatten wir das mit einer Notlösung, nämlich einer Konstante, gemacht; dafür sind Konstanten jedoch nicht gedacht. Besser ist die Verwendung eines Interface.

Definition

Bearbeiten

Ein Interface ("Schnittstelle") kann Konstanten und Methodensignaturen beinhalten. Wenn eine Klasse ein Interface implementiert, muss sie oder die Elternklasse alle Methoden des Interface besitzen. Die Methoden müssen exakt die gleiche Signatur haben, insbesondere die gleichen TypeHints. Im Gegensatz zur Vererbung können Klassen auch mehrere Interfaces implementieren, diese dürfen jedoch keine Methoden mit gleichem Namen haben, da PHP diesen Konflikt nicht auflösen kann.

Einfaches Interface

Bearbeiten
interface Sprecher {
  public function sagHallo();
}

Unser Baum kann nun dieses Interface mit dem Schlüsselwort implements implementieren:

class Baum implements Sprecher {
// restlicher Code
}

implements ersetzt hier übrigens nicht extends – Vererbung und die Implementierung von Interfaces können gleichzeitig benutzt werden.

Unser Baum ist nun gezwungen, alle Methoden des Interface anzubieten. Da das bereits der Fall ist, wird der Code weiterhin funktionieren.

TypeHinting und instanceof

Bearbeiten

TypeHinting kann auch für Interfaces verwendet werden:

//...
public function neuerSprecher(Sprecher $sprecher) {
//...

Auch der Operator instanceof funktioniert mit Interfaces.

Mehrere Interfaces

Bearbeiten

Nun braucht unsere Versammlung noch einen Vorstand, der die Versammlung eröffnet. Mit ein paar Änderungen sieht unsere Klasse nun so aus:

class Versammlung {

  protected $sprecher = array();
  protected $vorstand;

  public function neuerSprecher(Sprecher $sprecher) {
    $this->sprecher[] = $sprecher;
  }

  public function setzeVorstand(Vorstand $vorstand) {
    $this->vorstand = $vorstand;
  }

  public function alleStellenSichVor() {
    foreach ($this->sprecher as $sprecher) {
      $sprecher->sagHallo();
      echo '<br />';
    }
  }

  public function eroeffnen() {
    $this->vorstand->verleseTagesordnung();
  }
}

Nun brauchen wir das Interface Vorstand, welches die Methode verleseTagesordnung zwingend vorschreibt:

interface Vorstand {
  public function verleseTagesordnung();
}

Zum Schluss erweitern wir noch die Klasse Baum, sodass sie sowohl als Sprecher, wie auch als Vorstand auftritt:

class Baum implements Sprecher, Vorstand {

//...

public function verleseTagesordnung() {
  echo 'Punkt 1: Held Foo zum Ehrenmitglied ernennen. Punkt 2: ...';
}

Jetzt ist die Versammlung bereit, abgehalten zu werden:

$baum = new Baum();
$versammlung = new Versammlung();

$versammlung->neuerSprecher($baum);
$versammlung->setzeVorstand($baum);

$versammlung->alleStellenSichVor();
$versammlung->eroeffnen();

Ausgabe:

Hallo Welt!
Punkt 1: Held Foo zum Ehrenmitglied ernennen. Punkt 2: ...

Interfaces und Vererbung

Bearbeiten

Interfaces unterstützen ebenfalls die Vererbung. Soll zum Beispiel jeder Vorstand zwingend auch als Sprecher verstanden werden, lässt man das Interface Vorstand vom Interface Sprecher erben:

interface Vorstand extends Sprecher { //...

PHP-Dokumentation

Bearbeiten

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