Bitte erläutern Sie, wann ich ein PHP verwenden soll interface
und wann ich ein abstract class
?
Wie kann ich meine abstract class
in eine ändern interface
?
quelle
Bitte erläutern Sie, wann ich ein PHP verwenden soll interface
und wann ich ein abstract class
?
Wie kann ich meine abstract class
in eine ändern interface
?
Verwenden Sie eine Schnittstelle, wenn Sie Entwickler, die in Ihrem System arbeiten (Sie selbst eingeschlossen), dazu zwingen möchten, eine festgelegte Anzahl von Methoden für die Klassen zu implementieren, die sie erstellen werden.
Verwenden Sie eine abstrakte Klasse, wenn Sie Entwickler, die in Ihrem System arbeiten (Sie selbst eingeschlossen), dazu zwingen möchten, eine festgelegte Anzahl von Methoden zu implementieren, und wenn Sie einige Basismethoden bereitstellen möchten, die ihnen bei der Entwicklung ihrer untergeordneten Klassen helfen.
Beachten Sie außerdem, dass Clientklassen nur eine abstrakte Klasse erweitern können, während sie mehrere Schnittstellen implementieren können. Wenn Sie also Ihre Verhaltensverträge in abstrakten Klassen definieren, bedeutet dies, dass jede untergeordnete Klasse möglicherweise nur einem einzigen Vertrag entspricht. Manchmal ist dies eine gute Sache, wenn Sie Ihre Benutzerprogrammierer auf einen bestimmten Pfad zwingen möchten. In anderen Fällen wäre es schlecht. Stellen Sie sich vor, die Countable- und Iterator-Schnittstellen von PHP wären abstrakte Klassen anstelle von Schnittstellen.
Ein Ansatz, der häufig verwendet wird, wenn Sie sich nicht sicher sind, welchen Weg Sie einschlagen sollen (wie von Cletus unten erwähnt ), besteht darin, eine Schnittstelle zu erstellen und diese Schnittstelle dann von Ihrer abstrakten Klasse implementieren zu lassen.
abstract
und deninterface
Unterricht zu verstehen. Ihr Beitrag hat alles klar gemacht. Vielen Dank AlanDie Unterschiede zwischen einem
Abstract Class
und einemInterface
:Abstrakte Klassen
Eine abstrakte Klasse kann einige Funktionen bereitstellen und den Rest der abgeleiteten Klasse überlassen .
Die abgeleitete Klasse kann die in der Basisklasse definierten konkreten Funktionen überschreiben oder nicht .
Eine von einer abstrakten Klasse erweiterte untergeordnete Klasse sollte logisch verknüpft sein.
Schnittstelle
Eine Schnittstelle kann keine Funktionalität enthalten . Es enthält nur Definitionen der Methoden.
Die abgeleitete Klasse MUSS Code für alle in der Schnittstelle definierten Methoden bereitstellen .
Über eine Schnittstelle können völlig unterschiedliche und nicht verwandte Klassen logisch zusammengefasst werden.
quelle
abstract class X implements Y
undclass X implements Y
?abstract class X implements Y
Sie erklären, dass die Massenfunktionalität von X in einer abgeleiteten Klasse implementiert werden soll und dass sowohl die abstrakte als auch die abgeleitete Klasse in Y definierte Funktionen enthalten müssen , währendclass X implements Y
nur impliziert wird, dass Klasse X in Y definierte Funktionen enthalten muss. Wenn Ihre Schnittstelle Y. soll nicht von einer anderen Klasse als XI implementiert werden, würde die Definition von Y als Schnittstelle überspringen und nur die Funktionen in Y als öffentliche / geschützte / private abstrakte Funktion implementieren, um sicherzustellen, dass sie in der abgeleiteten Klasse implementiert sind.Warum abstrakte Klassen verwenden? Das Folgende ist ein einfaches Beispiel. Nehmen wir an, wir haben den folgenden Code:
Jetzt gebe ich dir einen Apfel und du isst ihn. Wie schmeckt es? Es schmeckt wie ein Apfel.
Wie schmeckt das? Nun, es macht nicht viel Sinn, also sollten Sie das nicht können. Dies wird erreicht, indem sowohl die Obstklasse als auch die darin enthaltene Essmethode abstrakt gemacht werden.
Eine abstrakte Klasse ist wie eine Schnittstelle, aber Sie können Methoden in einer abstrakten Klasse definieren, während sie in einer Schnittstelle alle abstrakt sind. Abstrakte Klassen können sowohl leere als auch arbeitende / konkrete Methoden haben. In Schnittstellen können dort definierte Funktionen keinen Körper haben. In abstrakten Klassen können sie.
Ein Beispiel aus der Praxis:
quelle
What does that taste like? Well, it doesn't make much sense, so you shouldn't be able to do that.
Jetzt kenne ich abstrakt!final
Schlüsselwort? Toller Beitrag, danke.Es wird empfohlen, eine Schnittstelle zu verwenden, um den Vertrag und eine abstrakte Klasse als nur eine Implementierung davon anzugeben. Diese abstrakte Klasse kann einen Großteil des Boilerplates ausfüllen, sodass Sie eine Implementierung erstellen können, indem Sie einfach überschreiben, was Sie benötigen oder wollen, ohne eine bestimmte Implementierung verwenden zu müssen.
quelle
Nur um dies in die Mischung zu bringen, aber wie Cletus erwähnte, indem ich eine Schnittstelle in Verbindung mit einer abstrakten Klasse verwendete, benutze ich die Schnittstelle oft, um mein Design-Denken zu verdeutlichen.
Zum Beispiel:
Auf diese Weise weiß jeder, der meinen Code liest (und weiß, was ein Dekorationsmuster ist), sofort a) wie ich meinen Parser erstelle und b) kann sehen, mit welchen Methoden das Dekorationsmuster implementiert wird.
Außerdem bin ich hier möglicherweise kein Java / C ++ / etc-Programmierer, aber hier können Datentypen ins Spiel kommen. Ihre Objekte sind von einem Typ, und wenn Sie sie weitergeben, ist der Typ programmatisch von Bedeutung. Wenn Sie Ihre kontrahierbaren Elemente in die Benutzeroberfläche verschieben, werden nur die von den Methoden zurückgegebenen Typen bestimmt, nicht jedoch der Basistyp der Klasse, die sie implementiert.
Es ist spät und ich kann mir kein besseres Psudo-Code-Beispiel vorstellen, aber hier ist:
quelle
Der Hauptunterschied besteht darin, dass eine abstrakte Klasse eine Standardimplementierung enthalten kann, eine Schnittstelle jedoch nicht.
Eine Schnittstelle ist ein Verhaltensvertrag ohne Implementierung.
quelle
Ich möchte hier nur hinzufügen, dass nur weil jede andere OO-Sprache eine Art von Schnittstellen und Abstraktion hat, dies nicht bedeutet, dass sie dieselbe Bedeutung und denselben Zweck haben wie in PHP. Die Verwendung von Abstraktion / Schnittstellen unterscheidet sich geringfügig, während Schnittstellen in PHP tatsächlich keine echte Funktion haben. Sie werden lediglich aus semantischen und schemabezogenen Gründen verwendet. Es geht darum, ein Projekt so flexibel wie möglich, erweiterbar und sicher für zukünftige Erweiterungen zu haben, unabhängig davon, ob der Entwickler später einen völlig anderen Nutzungsplan hat oder nicht.
Wenn Ihr Englisch nicht muttersprachlich ist, können Sie nachschlagen, was Abstraktion und Schnittstellen tatsächlich sind. Und suchen Sie auch nach Synonymen.
Und das könnte Ihnen als Metapher helfen:
SCHNITTSTELLE
Nehmen wir an, Sie backen eine neue Art Kuchen mit Erdbeeren und haben ein Rezept zusammengestellt, das die Zutaten und Schritte beschreibt. Nur Sie wissen, warum es so gut schmeckt und Ihre Gäste mögen es. Dann beschließen Sie, Ihr Rezept zu veröffentlichen, damit auch andere Leute diesen Kuchen probieren können.
Der Punkt hier ist
Genau DAS beschreibt Schnittstellen. Es ist eine Anleitung, eine Reihe von Anweisungen, die den Inhalt des Rezepts beachten. Genauso, als würden Sie ein Projekt in PHP erstellen und den Code auf GitHub oder mit Ihren Freunden oder was auch immer bereitstellen. Eine Schnittstelle ist das, was Menschen tun können und was Sie nicht tun sollten. Regeln, die es halten - wenn Sie einer nicht gehorchen, wird das gesamte Konstrukt gebrochen.
ABSTRAKTION
Um mit dieser Metapher hier fortzufahren ... stellen Sie sich vor, Sie sind diesmal der Gast, der diesen Kuchen isst. Dann probieren Sie diesen Kuchen jetzt nach dem Rezept. Sie möchten jedoch neue Zutaten hinzufügen oder die im Rezept beschriebenen Schritte ändern / überspringen. Was kommt als nächstes? Planen Sie eine andere Version dieses Kuchens. Diesmal mit schwarzen Beeren und nicht mit Strohbeeren und mehr Vanillecreme ... lecker.
Dies ist, was Sie eine Erweiterung des ursprünglichen Kuchens betrachten könnten. Sie machen im Grunde eine Abstraktion davon, indem Sie ein neues Rezept erstellen, weil es ein bisschen anders ist. Es hat ein paar neue Schritte und andere Zutaten. Die Black Berry-Version enthält jedoch einige Teile, die Sie vom Original übernommen haben - dies sind die grundlegenden Schritte, die jede Art von Kuchen haben muss. Wie Zutaten wie Milch - das hat jede abgeleitete Klasse.
Jetzt möchten Sie Zutaten und Schritte austauschen und diese MÜSSEN in der neuen Version dieses Kuchens definiert werden. Dies sind abstrakte Methoden die für den neuen Kuchen definiert werden müssen, weil der Kuchen eine Frucht enthalten sollte, aber welche? Also nimmst du diesmal die schwarzen Beeren. Erledigt.
Los geht's, Sie haben den Kuchen erweitert, sind der Benutzeroberfläche gefolgt und haben Schritte und Zutaten daraus abstrahiert.
quelle
Um einige der bereits ausgezeichneten Antworten zu ergänzen:
Mit abstrakten Klassen können Sie einen gewissen Grad an Implementierung bereitstellen. Schnittstellen sind reine Vorlagen. Eine Schnittstelle kann nur Funktionen definieren , sie kann sie niemals implementieren.
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, die Tatsache zu verwalten, dass PHP wie Java keine Mehrfachvererbung unterstützt. Eine PHP-Klasse kann nur einen einzelnen Elternteil erweitern. Sie können jedoch ein Klassenversprechen abgeben, so viele Schnittstellen zu implementieren, wie Sie möchten.
Typ: Für jede implementierte Schnittstelle nimmt die Klasse den entsprechenden Typ an. Da jede Klasse eine Schnittstelle (oder mehrere Schnittstellen) implementieren kann, verbinden Schnittstellen effektiv Typen, die ansonsten nicht miteinander zusammenhängen.
Eine Klasse kann sowohl eine Oberklasse erweitern als auch eine beliebige Anzahl von Schnittstellen implementieren:
Verwenden Sie eine Schnittstelle, wenn Sie nur eine Vorlage ohne Implementierung bereitstellen müssen, und Sie möchten sicherstellen, dass jede Klasse, die diese Schnittstelle implementiert, dieselben Methoden hat wie jede andere Klasse, die sie implementiert (zumindest).
Verwenden Sie eine abstrakte Klasse, wenn Sie eine Grundlage für andere Objekte erstellen möchten (eine teilweise erstellte Klasse). Die Klasse, die Ihre abstrakte Klasse erweitert, verwendet einige definierte / implementierte Eigenschaften oder Methoden:
Hier ist ein vereinfachter Fall / Beispiel. Nehmen Sie alle Implementierungsdetails heraus. Ändern Sie beispielsweise Ihre abstrakte Klasse von:
zu:
quelle
Aus phylosophischer Sicht:
Eine abstrakte Klasse repräsentiert eine "ist eine" Beziehung. Nehmen wir an, ich habe Früchte. Nun, ich hätte eine abstrakte Fruchtklasse, die gemeinsame Verantwortlichkeiten und Verhaltensweisen teilt.
Eine Schnittstelle repräsentiert eine "sollte" -Beziehung. Eine Schnittstelle sollte meiner Meinung nach (was die Meinung eines Junior-Entwicklers ist) durch eine Aktion oder etwas in der Nähe einer Aktion benannt werden (Entschuldigung, 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.
Aus codierender Sicht:
Wenn Ihre Objekte Code dupliziert haben, ist dies ein Hinweis darauf, dass sie ein allgemeines Verhalten aufweisen. Dies bedeutet, dass Sie möglicherweise eine abstrakte Klasse benötigen, um den Code wiederzuverwenden, was mit einer Schnittstelle nicht möglich ist.
Ein weiterer Unterschied besteht darin, dass ein Objekt so viele Schnittstellen implementieren kann, wie Sie benötigen. Aufgrund des "Diamantproblems" können Sie jedoch nur eine abstrakte Klasse haben (lesen Sie hier, um zu erfahren, warum! Http://en.wikipedia.org/wiki/ Mehrfachvererbung # The_diamond_problem )
Ich habe wahrscheinlich einige Punkte vergessen, aber ich hoffe, es kann die Dinge klären.
PS: Das "ist ein" / "sollte tun" wird von Vivek Vermanis Antwort gebracht, ich wollte seine Antwort nicht stehlen, nur um die Begriffe wiederzuverwenden, weil ich sie mochte!
quelle
Die technischen Unterschiede zwischen einer abstrakten Klasse und einer Schnittstelle sind in den anderen Antworten bereits genau aufgeführt. Ich möchte eine Erklärung hinzufügen, um zwischen einer Klasse und einer Schnittstelle zu wählen, während der Code für die objektorientierte Programmierung geschrieben wird.
Eine Klasse sollte eine Entität 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.
Es wurde entwickelt, um Ihnen eine Anzeigeschnittstelle bereitzustellen, daher sollte die Funktionalität durch eine Schnittstelle definiert werden.
Es gibt viele andere Dinge zu beachten, wie in den anderen Antworten erläutert, aber dies ist die grundlegendste Sache, die die meisten Leute beim Codieren ignorieren.
quelle
PHP
Ich wollte nur ein Beispiel hinzufügen, wann Sie möglicherweise beide verwenden müssen. Ich schreibe derzeit einen Datei-Handler, der an ein Datenbankmodell in einer Allzweck-ERP-Lösung gebunden ist.
Auf diese Weise habe ich mehrere Vorlagen für verschiedene Dateien und einen gemeinsamen Satz von Schnittstellenmethoden mit klarer Unterscheidung. Die Schnittstelle bietet die richtige Analogie zu den Zugriffsmethoden und nicht zu einer abstrakten Basisklasse.
Wenn ich später Adapter für verschiedene Dateispeicherdienste erstellen werde, wird diese Implementierung es ermöglichen, die Schnittstelle an anderer Stelle in völlig unterschiedlichen Kontexten zu verwenden.
quelle