OOP in PHP – Teil 11: Interfaces

Im letzten Artikel beschäftigten wir uns mit dem kleinen Schlüsselwort abstract. Dieses legt fest, dass eine Methode in einer Kindklasse überschrieben werden muss. Dasselbe können wir auch mit den sogenannten Interfaces (engl. Schnittstelle) erreichen.

Was ist ein Interface?

Kümmern wir uns zuerst um die grundlegende Frage: Was ist ein Interface überhaupt?
Ein Interface legt eine Schnittstelle für eine Klasse fest. Die Schnittstelle ist die Kommunikationsmöglichkeit mit der Klasse – also die Methoden. Simpel ausgedrückt können wir mit einem Interface also festlegen, welche Methoden eine Klasse implementieren muss.

Klingt sehr stark nach unserem vorher behandelten Schlüsselwort abstract, richtig? Richtig. Abstrakte Klassen unterscheiden sich allerdings von Interfaces in zwei großen Punkten:

  1. Ein Interface kann keine Methodenkörper definieren. Hier werden ausschließlich Methodensignaturen (also Sichtbarkeit, Name und Parameterliste) definiert! Die Sichtbarkeit in einem Interface muss allerdings immer public sein, schließlich stellt es eine Schnittstelle zur Außenwelt dar.
  2. Eine Klasse kann nur von einer anderen Klasse (abstract oder nicht) erben. Im Gegensatz dazu kann jede Klasse beliebig viele Interfaces implementieren.

Wozu ein Interface benutzen?

Was bringt uns so ein Interface denn nun? Indem wir ein Interface implementieren garantieren wir, dass eine Klasse einen gewissen Satz an Methoden mitbringt. Dies ist wieder gerade im Teamwork sehr hilfreich indem wir zum Beispiel ein Interface für gewisse Aufgaben definieren und unsere Kollegen so sehen, welche Methoden sie in ihren Klassen implementieren müssen um die Aufgabenstellung zu erfüllen.

Implementiert eine Klasse mehrere Interfaces gleichzeitig müssen alle Methoden definiert werden, die die Interfaces vorgeben.

Wie definieren wir ein Interface?

Die technische Seite der Interfaces ist glücklicherweise sehr simpel. Schauen wir uns zuerst an, wie wir ein Interface definieren.

Ähnlich wie bei einer Klasse definieren wir hier das Interface mit dem Schlüsselwort interface und einem Namen. Mehrere Interfaces können voneinander mit dem Schlüsselwort extends ableiten – genau wie Klassen.
Innerhalb des Interfaces legen wir nun beliebig viele Methodensignaturen fest (ohne geschweifte Klammern, denn die Methoden dürfen keinen Körper haben).

Möchten wir unser neu erstelltes Interface nun in einer Klasse implementieren benutzen wir dafür das Schlüsselwort implements.

Hier gilt zu beachten: Lassen wir eine der Methoden weg wirft PHP uns einen Fehler, da unsere Klasse dann nicht die Schnittstelle bereitstellt, die unser Interface festlegt.

Möchten wir mehrere Interfaces in einer Klasse implementieren können wir diese einfach per Komma getrennt anhängen. Außerdem kann eine Klasse natürlich sowohl von einer Elternklasse erben als auch Interfaces implementieren. Hier ein Beispiel:

11 Kommentare zu “OOP in PHP – Teil 11: Interfaces

  1. Endlich eine prägnante, verständliche Erklärung des Begriffs „Interfaces“ in der OOP. Zig UML Bücher vermochten das bei mir nicht!

  2. Hallo Frank.
    Dankeschön für das Tutorial.

    Dennoch Begriffsverwirrung für einen Anfänger.
    Methodenkörper == Klasse

    Stimmt…?

    LG

  3. Hallo Frank

    voriger Post ist unsinnig.

    Hätte nochmals lesen bzw. weiterlesen sollen.

    Ein Interface kann ebenkeine Funktion (Methode) „erstellen“.

    Entschludigung!

    LG thowe

    • Hi thowe,

      danke. 🙂
      Da gibt’s nix zu entschuldigen, wenn etwas nicht gleich klar ist kann man es sicher besser erklären.

      Der Methodenkörper ist der Code, den eine Funktion ausführt. Also der Codeblock zwischen den geschweiften Klammern der Methode. Und genau diesen können Interfaces nicht enthalten im Gegensatz zu abstrakten Klassen.

      Ich hoffe, das hat es nochmal etwas verdeutlicht. 🙂

      Viele Grüße
      Frank

  4. Hallo eins verstehe ich nicht. Es macht ja Sinn manche Methoden in einer Klasse für den Zugriff von außen zu schützen. Wenn ich aber eine Methode in einem Interface vorgebe ist sie public (kann also von außen aufgerufen werden).
    Versuche ich diese Methode in meiner Klasse auf protected zu ändern, bekomme ich die Fehlermeldung dass sie die gleiche Sichtbarkeit wie im Interface (also Public) haben muss.
    Dann nützt mir doch eigentlich ein Interface wenig, wenn ich hier nur öffentliche Methoden vorgeben darf.

    • Hi Tom,

      das ist genau der Sinn eines Interfaces. Interface auf Deutsch bedeutet Schnittstelle – das heißt hier gibst du die Schnittstelle (sprich: Funktionen) vor, auf die andere Parteien Zugriff erhalten.
      Andere Parteien könnten hier einerseits andere Programmierer sein, die einen Überblick über die Funktionalitäten deiner Klasse gewinnen wollen, die sie verwenden können.
      Genauso könnte es aber PHP selbst sein, wenn du ein Interface typehintest.

      Nehmen wir als Beispiel eine Autoklasse. public könnten hier die Methoden „zünden()“ und „gas_geben()“ sein. Alles, was den Fahrer interessiert, ist wie er diese Methoden benutzen kann. Dass im Hintergrund noch Dinge wie „benzin_einspritzen()“ ausgeführt werden ist nicht wichtig – deshalb ist es auch nicht in der Schnittstellendefinition (also im Interface).

      Ich hoffe, das klärt die Sache etwas auf 🙂

      Viele Grüße
      Frank

      • Hallo Frank,

        ja das war sehr bildlich. Ich hatte Interfaces als eine Art Dokumentation, bzw. besser gesagt Spezifikation. Dann denke ich braucht es ein Interface für alles öffentliche und eine Abstrakte Klasse für die Detailfunktionen, die dann die Unterklassen erben oder?

        Also z. B.

        interface iGeldautomat {
        function geheimzahlEingeben();
        function summeAuswählen();
        function geldAuszahlen();
        }

        abstract class geldautomat implemts iGeldautomat () {
        function geheimzahlEingeben() {
        }
        function summeAuswählen();
        }
        function geldAuszahlen() {
        }
        protected function geldDeponieren() {
        }
        protected function geldZähler() {
        }
        }

        class geldAutomatDeleux extends geldautomat {
        function geheimzahlEingeben() {
        }
        function summeAuswählen();
        }
        function geldAuszahlen() {
        }
        protected function geldDeponieren() {
        }
        protected function geldZähler() {
        }
        private function sendeGeldstandMitZentralRechner() {
        }
        }

        • Hi Tom,

          ja genau, das wäre eine Möglichkeit. So weiß jeder, der den Geldautomaten kennt (also sein Interface) was er damit machen kann. Wenn jemand aber selbst einen Geldautomat bauen möchte hat er den Bauplan (also die abstrakte Klasse) wo schon einige Funktionalitäten zur Verfügung stehen, die er nicht extra selbst einbauen muss.

          Viele Grüße
          Frank

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*