374 Stimmen

Schnittstelle oder abstrakte Klasse: was ist zu verwenden?

Bitte erklären Sie mir, wann ich ein PHP-Programm verwenden sollte interface und wann sollte ich eine abstract class ?

Wie ich mein Leben ändern kann abstract class in eine interface ?

22voto

Thielicious Punkte 3590

Außerdem möchte ich an dieser Stelle hinzufügen, dass, nur weil jede andere OO-Sprache eine Art von Schnittstellen und Abstraktion hat, dies nicht bedeutet, dass sie die gleiche Bedeutung und den gleichen Zweck wie in PHP haben. Die Verwendung von Abstraktion/Schnittstellen ist etwas anders, während Schnittstellen in PHP eigentlich keine wirkliche Funktion haben. Sie werden lediglich aus semantischen und schema-bezogenen Gründen verwendet. Es geht darum, ein Projekt so flexibel wie möglich, erweiterbar und sicher für zukünftige Erweiterungen zu machen, unabhängig davon, ob der Entwickler später einen völlig anderen Verwendungsplan hat oder nicht.

Wenn Ihr Englisch nicht muttersprachlich ist, sollten Sie nachschlagen, was Abstraktion und Schnittstellen eigentlich sind. Und suchen Sie auch nach Synonymen.

Und das könnte Ihnen als Metapher helfen:

INTERFACE

Nehmen wir an, Sie backen eine neue Art von Kuchen mit Erdbeeren und haben ein Rezept erstellt, in dem Sie die Zutaten und Schritte beschreiben. Nur Sie wissen, warum er so gut schmeckt und Ihre Gäste ihn mögen. Dann beschließen Sie, Ihr Rezept zu veröffentlichen, damit auch andere Leute diesen Kuchen probieren können.

Der Punkt ist hier

- um es richtig zu machen
**
- vorsichtig sein
- um Dinge zu vermeiden, die schlecht werden könnten (z. B. zu viele Erdbeeren oder so)
- um es für die Menschen, die es ausprobieren, einfach zu halten
- um Ihnen mitzuteilen, wie lange was zu tun ist (wie z. B. Rühren)
- zu sagen, welche Dinge man tun KANN, aber nicht tun MUSS
**

Genau DIES ist es, was Schnittstellen beschreibt. Es ist ein Leitfaden, eine Reihe von Anweisungen, die den Inhalt des Rezepts beachten. Genauso, wie wenn man ein Projekt in PHP erstellt und den Code auf GitHub oder bei seinen Kumpels oder was auch immer zur Verfügung stellen möchte. Eine Schnittstelle ist das, was man tun kann und was man nicht tun sollte. Regeln, die es halten - wenn man gegen eine verstößt, wird das gesamte Konstrukt gebrochen.

ABSCHREIBUNG

Um mit dieser Metapher fortzufahren... stellen Sie sich vor, dass Sie diesmal der Gast sind, der diesen Kuchen isst. Dann probieren Sie diesen Kuchen jetzt nach diesem Rezept. Aber Sie möchten neue Zutaten hinzufügen oder die im Rezept beschriebenen Schritte ändern/auslassen. Was kommt also als nächstes? Sie planen eine andere Version des Kuchens. Diesmal mit schwarzen Beeren und nicht mit Strohbeeren und mehr Vanillecreme...lecker.

Dies ist sozusagen eine Erweiterung des ursprünglichen Kuchens. Im Grunde genommen abstrahiert man davon, indem man ein neues Rezept erstellt, weil es ein bisschen anders ist. Es hat ein paar neue Schritte und andere Zutaten. Allerdings hat die Schwarzbeeren-Version einige Teile, die du vom Original übernommen hast - das sind die Basisschritte, die jede Art von Kuchen haben muss. Zutaten wie Milch - das hat jede abgeleitete Klasse.

Jetzt wollen Sie Zutaten und Schritte austauschen, und diese MÜSSEN in der neuen Version des Kuchens definiert werden. Diese sind abstrakte Methoden die für den neuen Kuchen definiert werden müssen, denn es soll eine Frucht im Kuchen sein, aber welche? Also nimmst du dieses Mal die schwarzen Beeren. Erledigt.

Das war's. Sie haben den Kuchen erweitert, sind der Schnittstelle gefolgt und haben Schritte und Zutaten davon abstrahiert.

20voto

Mitch Wheat Punkte 287474

Der Hauptunterschied besteht darin, dass eine abstrakte Klasse eine Standardimplementierung enthalten kann, während dies bei einer Schnittstelle nicht möglich ist.

Eine Schnittstelle ist ein Verhaltenskontrakt ohne jegliche Implementierung.

18voto

bg17aw Punkte 2523

Um einige der bereits ausgezeichneten Antworten zu ergänzen:

  • Bei abstrakten Klassen können Sie ein gewisses Maß an Implementierung bereitstellen, bei Schnittstellen handelt es sich um reine Vorlagen. Eine Schnittstelle kann nur definieren Funktionalität kann er sie niemals umsetzen.

  • Jede Klasse, die die Schnittstelle implementiert, verpflichtet sich, alle von ihr definierten Methoden zu implementieren, oder sie muss als abstrakt deklariert werden.

  • Schnittstellen können dabei helfen, mit der Tatsache umzugehen, dass PHP, wie Java, keine Mehrfachvererbung unterstützt. Eine PHP-Klasse kann nur eine einzige Elternklasse erweitern. Sie können jedoch einer Klasse das Versprechen geben, so viele Schnittstellen zu implementieren, wie Sie wollen.

  • Typ: Für jede Schnittstelle, die sie implementiert, nimmt die Klasse den entsprechenden Typ an. Denn jede Klasse kann eine Schnittstelle (oder mehrere Schnittstellen) implementieren, können Schnittstellen Typen, die ansonsten nicht miteinander verbunden sind, effektiv verbinden.

  • eine Klasse kann sowohl eine Oberklasse erweitern als auch eine beliebige Anzahl von Schnittstellen implementieren:

    class SubClass extends ParentClass implements Interface1, Interface2 {
        // ...
    }

Bitte erklären Sie, wann ich eine Schnittstelle und wann eine abstrakte Klasse verwenden sollte?

Verwenden Sie eine Schnittstelle, wenn Sie nur eine Vorlage ohne jegliche Implementierung bereitstellen müssen, und Sie sicherstellen wollen, dass jede Klasse, die diese Schnittstelle implementiert, die gleichen Methoden hat wie jede andere Klasse, die sie (mindestens) implementiert.

Verwenden Sie eine abstrakte Klasse, wenn Sie eine Grundlage für andere Objekte schaffen wollen (eine teilweise gebaute Klasse). Die Klasse, die Ihre abstrakte Klasse erweitert, verwendet einige definierte/implementierte Eigenschaften oder Methoden:

<?php
// interface
class X implements Y { } // this is saying that "X" agrees to speak language "Y" with your code.

// abstract class
class X extends Y { } // this is saying that "X" is going to complete the partial class "Y".
?>

Wie kann ich meine abstrakte Klasse in eine Schnittstelle umwandeln?

Hier ein vereinfachter Fall/Beispiel. Nehmen Sie alle Implementierungsdetails heraus. Ändern Sie zum Beispiel Ihre abstrakte Klasse von:

abstract class ClassToBuildUpon {
    public function doSomething() {
          echo 'Did something.';
    }
}

zu:

interface ClassToBuildUpon {
    public function doSomething();
}

13voto

IEatBagels Punkte 817

Von einem phylosophischen Standpunkt aus betrachtet :

  • Eine abstrakte Klasse stellt eine "ist ein"-Beziehung dar. Sagen wir, ich habe Früchte, dann hätte ich eine abstrakte Klasse Fruit, die gemeinsame Verantwortlichkeiten und gemeinsames Verhalten teilt.

  • Eine Schnittstelle stellt eine "sollte tun"-Beziehung dar. Eine Schnittstelle sollte meiner Meinung nach (und das ist die Meinung eines Junior-Entwicklers) durch eine Aktion oder etwas, das einer Aktion nahe kommt, benannt werden (Sorry, ich kann das Wort nicht finden, ich bin kein englischer Muttersprachler), sagen wir IEatable. Sie wissen, dass es gegessen werden kann, aber Sie wissen nicht, was Sie essen.

Vom Standpunkt der Kodierung aus betrachtet:

  • Wenn Ihre Objekte doppelten Code aufweisen, ist dies ein Hinweis darauf, dass sie ein gemeinsames Verhalten haben, was bedeutet, dass Sie möglicherweise eine abstrakte Klasse benötigen, um den Code wiederzuverwenden, was Sie mit einer Schnittstelle nicht tun können.

  • Ein weiterer Unterschied besteht darin, dass ein Objekt beliebig viele Schnittstellen implementieren kann, aber wegen des "Diamantproblems" nur eine abstrakte Klasse haben kann (lesen Sie hier, warum! http://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem )

Wahrscheinlich habe ich einige Punkte vergessen, aber ich hoffe, dass ich damit die Dinge klären kann.

PS: Das "ist ein"/"sollte ein" stammt aus der Antwort von Vivek Vermani, ich wollte seine Antwort nicht klauen, sondern nur die Begriffe wiederverwenden, weil sie mir gefallen haben!

8voto

Anurag Sharma Punkte 491

Die technischen Unterschiede zwischen einer abstrakten Klasse und einer Schnittstelle sind bereits in den anderen Antworten genau aufgeführt. Ich möchte eine Erklärung hinzufügen, um beim Schreiben des Codes im Sinne der objektorientierten Programmierung zwischen einer Klasse und einer Schnittstelle zu wählen.

Eine Klasse sollte eine Einheit darstellen, während eine Schnittstelle das Verhalten darstellen sollte.

Nehmen wir ein Beispiel. Ein Computermonitor ist eine Entität und sollte als Klasse dargestellt werden.

class Monitor{
    private int monitorNo;
}

Es soll Ihnen eine Anzeigeschnittstelle zur Verfügung stellen, daher sollte die Funktionalität durch eine Schnittstelle definiert werden.

interface Display{
    void display();
}

Es gibt noch viele andere Dinge zu beachten, wie in den anderen Antworten erklärt, aber dies ist die grundlegendste Sache, die die meisten Leute beim Programmieren ignorieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X