Was ist der Sinn von Schnittstellen in PHP?


224

Mit Schnittstellen können Sie Code erstellen, der die Methoden der Klassen definiert, die ihn implementieren. Sie können diesen Methoden jedoch keinen Code hinzufügen.

Mit abstrakten Klassen können Sie dasselbe tun und der Methode Code hinzufügen.

Wenn Sie nun dasselbe Ziel mit abstrakten Klassen erreichen können, warum brauchen wir dann überhaupt das Konzept von Schnittstellen?

Mir wurde gesagt, dass es mit der OO-Theorie von C ++ bis Java zu tun hat, worauf PHPs OO-Zeug basiert. Ist das Konzept in Java nützlich, aber nicht in PHP? Ist es nur ein Weg, um zu verhindern, dass Platzhalter in der abstrakten Klasse verstreut sind? Vermisse ich etwas


4
Sie müssen dies lesen: stackoverflow.com/a/384067/14673
Luc M

Ich bin mir ziemlich sicher, dass es eine mentale Hilfe und eine Kommunikationshilfe ist. Schnittstellen dienen als hervorragende Lehrmittel für Ihre API, da sie die Dienste, die Ihre API bereitstellt, auf abstrakte Weise bündeln und ohne Kenntnis der Implementierung gelesen werden können. Dies ist teuer, aber Personen, die mit der Benutzeroberfläche vertraut sind, können die Funktionen bereits direkt verwenden, ohne Klassen zu benötigen, wodurch ein Zeiger gespeichert wird. Ohne sprachdefinierte Schnittstellen kann es für viele Programmierer schwierig sein, vorauszuplanen, da Menschen, die früher "oop-Sprachen" verwendet haben, es oft vorziehen, mit Schnittstellen zu entwerfen, anstatt auf Papier.
Dmitry

Antworten:


142

Der gesamte Sinn von Schnittstellen besteht darin, Ihnen die Flexibilität zu geben, dass Ihre Klasse gezwungen wird, mehrere Schnittstellen zu implementieren, aber dennoch keine Mehrfachvererbung zulässt. Die Probleme beim Erben von mehreren Klassen sind vielfältig und die Wikipedia- Seite fasst sie ziemlich gut zusammen.

Schnittstellen sind ein Kompromiss. Die meisten Probleme mit der Mehrfachvererbung gelten nicht für abstrakte Basisklassen. Daher deaktivieren die meisten modernen Sprachen heutzutage die Mehrfachvererbung, rufen jedoch Schnittstellen für abstrakte Basisklassen auf und ermöglichen es einer Klasse, so viele dieser Klassen zu "implementieren", wie sie möchten.


39
Es kann auch gesagt werden, dass * Interfaces das Design für eine Klasse ohne Implementierung liefern. * Abstrakte Klassen bieten Design und Implementierung. Abstrakte Klassen sind am nützlichsten, wenn untergeordnete Klassen einige Implementierungsähnlichkeiten aufweisen, sich jedoch in bestimmten Implementierungen unterscheiden.
Jrgns

@Craig, es gibt kein inhärentes Problem bei der Mehrfachvererbung, nur dass die aktuellen Sprachen nicht leistungsfähig genug sind, um sie ordnungsgemäß zu implementieren. Die "Probleme" können tatsächlich ziemlich einfach behoben werden, zum Beispiel kann die Angabe des expliziten Vererbungspfads für geerbte Funktionen mit demselben Namen das Diamantendilemma lösen.
Pacerier

15
Darum geht es bei Schnittstellen überhaupt nicht. Es handelt sich nicht um einen Kompromiss bei der Mehrfachvererbung, sondern um die Erstellung eines konzeptionellen und abstrakten Vertrags für zu implementierende Objekte und für andere zu konsumierende Objekte / Methoden. Schnittstellen sind ein Werkzeug für den Polymorphismus und nicht für die direkte Vererbung.
Madaras Geist

123

Das Konzept ist in der objektorientierten Programmierung rundum nützlich. Für mich ist eine Schnittstelle ein Vertrag. Solange meine Klasse und Ihre Klasse sich auf diesen Methodensignaturvertrag einigen, können wir eine "Schnittstelle" herstellen. Was abstrakte Klassen betrifft, so sehe ich eher Basisklassen, die einige Methoden auslöschen, und ich muss die Details ausfüllen.


Das hat mich ein bisschen verstehen lassen. Es ist wie bei Namespaces - so ist gemeinsam genutzter Code einfacher zu verwenden und ohne Konflikte. Es ist einfacher, wenn zwei Leute Unterricht auf derselben Basis geben, oder?
RedClover

Müssen wir nicht das allgemeine Konzept einer 'Schnittstelle' von den konkreten Schnittstellen in einer Sprache wie PHP unterscheiden? Jede Funktion verfügt beispielsweise über eine "Schnittstelle", die definiert, wie Sie sie verwenden, und deren Implementierung verbirgt. Für diese Art von "vertraglicher" Schnittstelle ist also keine spezielle Sprachfunktion erforderlich. Daher muss die
Sprachfunktion

70

Warum brauchen Sie eine Schnittstelle, wenn es bereits abstrakte Klassen gibt? Um Mehrfachvererbung zu verhindern (kann mehrere bekannte Probleme verursachen).

Eines dieser Probleme:

Das "Diamantproblem" (manchmal als "tödlicher Diamant des Todes" bezeichnet) ist eine Mehrdeutigkeit, die entsteht, wenn zwei Klassen B und C von A und Klasse D sowohl von B als auch von C erben. Wenn es in A eine Methode gibt, die B und C haben überschrieben, und D überschreibt es nicht. Welche Version der Methode erbt D dann: die von B oder die von C?

Quelle: https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem

Warum / wann eine Schnittstelle verwenden? Ein Beispiel ... Alle Autos auf der Welt haben die gleiche Schnittstelle (Methoden) ... AccelerationPedalIsOnTheRight(), BrakePedalISOnTheLeft(). Stellen Sie sich vor, jede Automarke hätte diese "Methoden" anders als eine andere Marke. BMW hätte die Bremsen auf der rechten Seite und Honda hätte die Bremsen auf der linken Seite des Rades. Die Leute müssten jedes Mal lernen, wie diese "Methoden" funktionieren, wenn sie eine andere Automarke kaufen. Aus diesem Grund ist es eine gute Idee, dieselbe Benutzeroberfläche an mehreren "Stellen" zu verwenden.

Was macht eine Schnittstelle für Sie (warum sollte jemand überhaupt eine verwenden)? Eine Schnittstelle verhindert, dass Sie "Fehler" machen (sie stellt sicher, dass alle Klassen, die eine bestimmte Schnittstelle implementieren, über die Methoden verfügen, die sich in der Schnittstelle befinden).

// Methods inside this interface must be implemented in all classes which implement this interface.
interface IPersonService
{   
    public function Create($personObject);
}

class MySqlPerson implements IPersonService
{
    public function Create($personObject)
    {
        // Create a new person in MySql database.
    }
}

class MongoPerson implements IPersonService
{
    public function Create($personObject)
    {
        // Mongo database creates a new person differently then MySQL does. But the code outside of this method doesn't care how a person will be added to the database, all it has to know is that the method Create() has 1 parameter (the person object).
    }
}

Auf diese Weise wird die Create()Methode immer auf die gleiche Weise verwendet. Es spielt keine Rolle, ob wir die MySqlPersonKlasse oder die MongoPersonKlasse verwenden. Die Art und Weise, wie wir eine Methode verwenden, bleibt gleich (die Schnittstelle bleibt gleich).

Zum Beispiel wird es so verwendet (überall in unserem Code):

new MySqlPerson()->Create($personObject);
new MongoPerson()->Create($personObject);

Auf diese Weise kann so etwas nicht passieren:

new MySqlPerson()->Create($personObject)
new MongoPerson()->Create($personsName, $personsAge);

Es ist viel einfacher, sich an eine Schnittstelle zu erinnern und überall dieselbe zu verwenden, als mehrere verschiedene.

Auf diese Weise kann das Innere der Create()Methode für verschiedene Klassen unterschiedlich sein, ohne den "äußeren" Code zu beeinflussen, der diese Methode aufruft. Der externe Code muss lediglich wissen, dass die Methode Create()1 parameter ( $personObject) hat, da der externe Code die Methode auf diese Weise verwendet / aufruft. Dem externen Code ist es egal, was innerhalb der Methode passiert. es muss nur wissen, wie man es benutzt / nennt.

Sie können dies auch ohne Schnittstelle tun, aber wenn Sie eine Schnittstelle verwenden, ist diese "sicherer" (weil Sie dadurch keine Fehler machen können). Die Schnittstelle stellt sicher, dass die Methode Create()in allen Klassen, die die Schnittstelle implementieren, dieselbe Signatur (dieselben Typen und dieselbe Anzahl von Parametern) hat. Auf diese Weise können Sie sicher sein, dass JEDE Klasse, die die IPersonServiceSchnittstelle implementiert , die Methode Create()(in diesem Beispiel) hat und nur 1 Parameter ( $personObject) benötigt, um aufgerufen / verwendet zu werden.

Eine Klasse, die eine Schnittstelle implementiert, muss alle Methoden implementieren, die die Schnittstelle ausführt / hat.

Ich hoffe, dass ich mich nicht zu oft wiederholt habe.


Wirklich schöne Analogie zu den Auto-Pedalen!
James

24

Der Unterschied zwischen der Verwendung einer Schnittstelle und einer abstrakten Klasse hat für mich mehr mit der Codeorganisation zu tun als mit der Durchsetzung durch die Sprache selbst. Ich verwende sie häufig, wenn ich Code für andere Entwickler vorbereite, damit sie innerhalb der beabsichtigten Entwurfsmuster bleiben. Schnittstellen sind eine Art "Design by Contract", bei dem Ihr Code sich bereit erklärt, auf einen vorgeschriebenen Satz von API-Aufrufen zu antworten, die möglicherweise von Code stammen, auf den Sie keinen Zugriff haben.

Während die Vererbung von abstrakten Klassen eine "ist eine" Beziehung ist, ist dies nicht immer das, was Sie wollen, und das Implementieren einer Schnittstelle ist eher eine "verhält sich wie eine" Beziehung. Dieser Unterschied kann in bestimmten Zusammenhängen sehr bedeutend sein.

Angenommen, Sie haben ein abstraktes Klassenkonto, von dem viele andere Klassen ausgehen (Kontotypen usw.). Es gibt bestimmte Methoden, die nur für diese Typgruppe gelten. Einige dieser Kontounterklassen implementieren jedoch Versionable, Listable oder Editable, sodass sie in Controller geworfen werden können, die diese APIs verwenden möchten. Dem Controller ist es egal, um welchen Objekttyp es sich handelt

Im Gegensatz dazu kann ich auch ein Objekt erstellen, das sich nicht von Account aus erstreckt, z. B. eine abstrakte Benutzerklasse, und dennoch Listable and Editable, aber nicht Versionable implementieren, was hier keinen Sinn ergibt.

Auf diese Weise sage ich, dass die FooUser-Unterklasse KEIN Konto ist, sondern sich wie ein bearbeitbares Objekt verhält. Ebenso erstreckt sich BarAccount von Account, ist jedoch keine Benutzerunterklasse, sondern implementiert Editable, Listable und auch Versionable.

Das Hinzufügen all dieser APIs für Editable, Listable und Versionable zu den abstrakten Klassen selbst wäre nicht nur unübersichtlich und hässlich, sondern würde entweder die allgemeinen Schnittstellen in Account und User duplizieren oder mein User-Objekt zwingen, Versionable zu implementieren, wahrscheinlich nur, um eine zu werfen Ausnahme.


Das ist es genau hier. Erzwingen Sie rigoros Entwickler, Ihre Methoden zu verwenden, ohne sie zu erweitern oder zu überschreiben
Nick

21

Schnittstellen sind im Wesentlichen eine Blaupause für das, was Sie erstellen können. Sie definieren, welche Methoden eine Klasse haben muss , aber Sie können zusätzliche Methoden außerhalb dieser Einschränkungen erstellen.

Ich bin mir nicht sicher, was Sie damit meinen, dass Sie Methoden keinen Code hinzufügen können - weil Sie das können. Wenden Sie die Schnittstelle auf eine abstrakte Klasse oder die Klasse an, die sie erweitert?

Eine Methode in der Schnittstelle, die auf die abstrakte Klasse angewendet wird, muss in dieser abstrakten Klasse implementiert werden. Wenden Sie diese Schnittstelle jedoch auf die Erweiterungsklasse an, und die Methode muss nur in der Erweiterungsklasse implementiert werden. Ich könnte mich hier irren - ich benutze Schnittstellen nicht so oft, wie ich könnte / sollte.

Ich habe mir Schnittstellen immer als Muster für externe Entwickler oder als zusätzlichen Regelsatz vorgestellt, um sicherzustellen, dass die Dinge korrekt sind.


9
In PHP enthalten Schnittstellen nur die Methodendeklaration und nicht die eigentliche Implementierung. Mit abstrakten Klassen können Sie jedoch den Methoden "Code hinzufügen", die von den Klassen geerbt werden sollen, die sie erweitern. Ich glaube, auf diesen Unterschied bezog sich mk.
Nocash

13

Sie werden Schnittstellen in PHP verwenden:

  1. So verbergen Sie die Implementierung: Richten Sie ein Zugriffsprotokoll für eine Objektklasse ein und ändern Sie die zugrunde liegende Implementierung, ohne an allen Stellen, an denen Sie diese Objekte verwendet haben, ein Refactoring durchzuführen
  2. So überprüfen Sie den Typ: Stellen Sie sicher, dass ein Parameter einen bestimmten Typ hat $object instanceof MyInterface
  3. So erzwingen Sie die Parameterprüfung zur Laufzeit
  4. So implementieren Sie mehrere Verhaltensweisen in einer einzigen Klasse (komplexe Typen erstellen)

    Klasse Auto implementiert EngineInterface, BodyInterface, SteeringInterface {

so , dass ein CarObjekt ca jetzt start(), stop()(EngineInterface) oder goRight(),goLeft() (Steering - Schnittstelle)

und andere Dinge, an die ich momentan nicht denken kann

Nummer 4 ist wahrscheinlich der offensichtlichste Anwendungsfall, den Sie nicht mit abstrakten Klassen behandeln können.

Vom Denken in Java:

Eine Schnittstelle sagt: "So sehen alle Klassen aus, die diese bestimmte Schnittstelle implementieren." Somit weiß jeder Code, der eine bestimmte Schnittstelle verwendet, welche Methoden für diese Schnittstelle aufgerufen werden können, und das ist alles. Die Schnittstelle wird also verwendet, um ein „Protokoll“ zwischen Klassen zu erstellen.


10

Schnittstellen existieren nicht als Basis, auf der Klassen erweitert werden können, sondern als Karte der erforderlichen Funktionen.

Das folgende Beispiel zeigt die Verwendung einer Schnittstelle, in die eine abstrakte Klasse nicht passt:
Nehmen wir an, ich habe eine Kalenderanwendung, mit der Benutzer Kalenderdaten aus externen Quellen importieren können. Ich würde Klassen schreiben, um den Import jeder Art von Datenquelle (ical, rss, atom, json) zu handhaben. Jede dieser Klassen würde eine gemeinsame Schnittstelle implementieren, die sicherstellen würde, dass alle über die gemeinsamen öffentlichen Methoden verfügen, die meine Anwendung zum Abrufen der Daten benötigt.

<?php

interface ImportableFeed 
{
    public function getEvents();
}

Wenn ein Benutzer dann einen neuen Feed hinzufügt, kann ich den Typ des Feeds identifizieren und die für diesen Typ entwickelte Klasse zum Importieren der Daten verwenden. Jede Klasse, die zum Importieren von Daten für einen bestimmten Feed geschrieben wurde, hat einen völlig anderen Code. Andernfalls gibt es möglicherweise nur sehr wenige Ähnlichkeiten zwischen den Klassen, außer dass sie für die Implementierung der Schnittstelle erforderlich sind, über die meine Anwendung sie verwenden kann. Wenn ich eine abstrakte Klasse verwenden würde, könnte ich sehr leicht die Tatsache ignorieren, dass ich die getEvents () -Methode nicht überschrieben habe, die dann meine Anwendung in diesem Fall beschädigen würde, während die Verwendung einer Schnittstelle meine App nicht ausführen würde, wenn eine der Methoden vorhanden wäre In der Schnittstelle definierte sind in der Klasse, die sie implementiert hat, nicht vorhanden. Meine App muss sich nicht darum kümmern, welche Klasse sie verwendet, um Daten aus einem Feed abzurufen.

Um noch einen Schritt weiter zu gehen, erweist sich die Benutzeroberfläche als äußerst nützlich, wenn ich zu meiner Kalender-App zurückkehre, um einen weiteren Feed-Typ hinzuzufügen. Durch die Verwendung der ImportableFeed-Schnittstelle kann ich weitere Klassen hinzufügen, die verschiedene Feed-Typen importieren, indem ich einfach neue Klassen hinzufüge, die diese Schnittstelle implementieren. Auf diese Weise kann ich Tonnen von Funktionen hinzufügen, ohne meine Kernanwendung unnötig erweitern zu müssen, da meine Kernanwendung nur darauf angewiesen ist, dass die öffentlichen Methoden verfügbar sind, die für die Schnittstelle erforderlich sind, solange meine neuen Feed-Importklassen die ImportableFeed-Schnittstelle implementieren Ich weiß, ich kann es einfach fallen lassen und in Bewegung bleiben.

Dies ist nur ein sehr einfacher Anfang. Ich kann dann eine andere Schnittstelle erstellen, für deren Implementierung alle meine Kalenderklassen erforderlich sein können, die mehr Funktionen bietet, die für den von der Klasse behandelten Feed-Typ spezifisch sind. Ein weiteres gutes Beispiel wäre eine Methode zur Überprüfung des Futtertyps usw.

Dies geht über die Frage hinaus, aber da ich das obige Beispiel verwendet habe: Schnittstellen haben ihre eigenen Probleme, wenn sie auf diese Weise verwendet werden. Ich muss sicherstellen, dass die Ausgabe, die von den implementierten Methoden zurückgegeben wird, um mit der Schnittstelle übereinzustimmen, und um dies zu erreichen, verwende ich eine IDE, die PHPDoc-Blöcke liest und den Rückgabetyp als Typhinweis in einen PHPDoc-Block der Schnittstelle einfügt, der dann wird Übersetzen Sie in die konkrete Klasse, die es implementiert. Meine Klassen, die die Datenausgabe der Klassen verwenden, die diese Schnittstelle implementieren, wissen dann zumindest, dass sie ein in diesem Beispiel zurückgegebenes Array erwarten:

<?php
interface ImportableFeed 
{
    /**
     * @return array
     */
    public function getEvents();
}

Es gibt nicht viel Raum, um abstrakte Klassen und Schnittstellen zu vergleichen. Schnittstellen sind einfach Karten, bei deren Implementierung die Klasse über eine Reihe öffentlicher Schnittstellen verfügen muss.


Gute Erklärung :) Danke!
Razvan.432

Nur um Informationen hinzuzufügen: Wenn Sie in der abstrakten Klasse die Methode als abstrakt deklarieren, verhält sie sich wie eine Schnittstelle, sodass Sie die Tatsache nicht ignorieren können, dass Sie getEvents () nicht überschrieben haben. Die App würde genauso versagen wie mit der Benutzeroberfläche.
Rikudou_Sennin

8

Schnittstellen dienen nicht nur dazu, sicherzustellen, dass Entwickler bestimmte Methoden implementieren. Die Idee ist, dass Sie diese Methoden verwenden können, da diese Klassen garantiert über bestimmte Methoden verfügen, auch wenn Sie den tatsächlichen Typ der Klasse nicht kennen. Beispiel:

interface Readable {
  String read();
}

List<Readable> readables; // dunno what these actually are, but we know they have read();
for(Readable reader : readables)
  System.out.println(reader.read());

In vielen Fällen ist es nicht sinnvoll, eine Basisklasse bereitzustellen, ob abstrakt oder nicht, da die Implementierungen stark variieren und außer einigen Methoden nichts gemeinsam haben.

Dynamisch typisierte Sprachen haben den Begriff "Ententypisierung", bei der Sie keine Schnittstellen benötigen. Es steht Ihnen frei anzunehmen, dass das Objekt die Methode hat, die Sie aufrufen. Dies umgeht das Problem in statisch typisierten Sprachen, in denen Ihr Objekt über eine Methode verfügt (in meinem Beispiel read ()), die Schnittstelle jedoch nicht implementiert.


6

Meiner Meinung nach sollten Schnittstellen nicht funktionalen abstrakten Klassen vorgezogen werden. Es würde mich nicht wundern, wenn es dort überhaupt einen Performance-Hit geben würde, da nur ein Objekt instanziiert wird, anstatt zwei zu analysieren und zu kombinieren (obwohl ich nicht sicher bin, ob ich mit dem Innenleben nicht vertraut bin von OOP PHP).

Es ist wahr, dass Schnittstellen weniger nützlich / sinnvoll sind als beispielsweise im Vergleich zu Java. Auf der anderen Seite wird PHP6 noch mehr Typhinweise einführen, einschließlich Typhinweise für Rückgabewerte. Dies sollte den PHP-Schnittstellen einen gewissen Mehrwert verleihen.

tl; dr: interfaces definiert eine Liste von Methoden, die befolgt werden müssen (think API), während eine abstrakte Klasse einige grundlegende / allgemeine Funktionen bietet, die die Unterklassen an bestimmte Anforderungen anpassen.


PHP 6 wird niemals veröffentlicht. PHP 6 war ein Projekt, das von 2005 bis 2010 entwickelt wurde, aber verzögert und schließlich abgebrochen wurde. PHP 7 ist die nächste Version, hauptsächlich um Verwechslungen mit dem früheren PHP 6-Projekt zu vermeiden.
Ashu Jha

5

Ich kann mich nicht erinnern, ob PHP in dieser Hinsicht anders ist, aber in Java können Sie mehrere Schnittstellen implementieren, aber Sie können nicht mehrere abstrakte Klassen erben. Ich würde annehmen, dass PHP genauso funktioniert.

In PHP können Sie mehrere Schnittstellen anwenden, indem Sie sie durch ein Komma trennen (ich denke, ich finde das keine saubere Lösung).

Bei mehreren abstrakten Klassen können sich mehrere Abstracts gegenseitig erweitern (auch hier bin ich mir nicht ganz sicher, aber ich glaube, ich habe das schon einmal gesehen). Das einzige, was Sie nicht erweitern können, ist eine Abschlussklasse.


4

Schnittstellen geben Ihrem Code keine Leistungssteigerungen oder ähnliches, aber sie können einen großen Beitrag zur Wartung leisten. Es ist wahr, dass eine abstrakte Klasse (oder sogar eine nicht abstrakte Klasse) verwendet werden kann, um eine Schnittstelle zu Ihrem Code einzurichten, aber geeignete Schnittstellen (die Sie mit dem Schlüsselwort definieren und die nur Methodensignaturen enthalten) sind einfach einfacher zu verwenden sortieren und lesen.

Abgesehen davon neige ich dazu, bei der Entscheidung, ob eine Schnittstelle über eine Klasse verwendet werden soll oder nicht, Diskretion zu walten. Manchmal möchte ich Standardmethodenimplementierungen oder Variablen, die allen Unterklassen gemeinsam sind.

Natürlich ist der Punkt bei der Implementierung mehrerer Schnittstellen auch ein vernünftiger. Wenn Sie eine Klasse haben, die mehrere Schnittstellen implementiert, können Sie ein Objekt dieser Klasse als verschiedene Typen in derselben Anwendung verwenden.

Die Tatsache, dass es sich bei Ihrer Frage um PHP handelt, macht die Dinge jedoch etwas interessanter. Das Tippen auf Schnittstellen ist in PHP immer noch nicht unbedingt erforderlich, da Sie jeder Methode unabhängig von ihrem Typ so ziemlich alles zuführen können. Sie können Methodenparameter statisch eingeben, aber ein Teil davon ist fehlerhaft (String verursacht meines Erachtens Schluckauf). Kombinieren Sie dies mit der Tatsache, dass Sie die meisten anderen Referenzen nicht eingeben können und es nicht viel Wert ist, die statische Eingabe in PHP zu erzwingen ( zu diesem Zeitpunkt ). Und aus diesem Grund ist der Wert von Schnittstellen in PHP , an diesem Punktist weit weniger als in stärker typisierten Sprachen. Sie haben den Vorteil der Lesbarkeit, aber sonst wenig. Die Mehrfachimplementierung ist nicht einmal vorteilhaft, da Sie die Methoden noch deklarieren und ihnen im Implementierer Text geben müssen.


2

Nachfolgend finden Sie die Punkte für die PHP-Schnittstelle

  1. Es wird verwendet, um die erforderliche Anzahl von Methoden in der Klasse zu definieren [wenn Sie HTML laden möchten, sind ID und Name erforderlich. In diesem Fall umfassen die Schnittstellen setID und setName].
  2. Die Schnittstelle erzwingt streng, dass die Klasse alle darin definierten Methoden enthält.
  3. Sie können die Methode nur in einer Schnittstelle mit öffentlicher Zugänglichkeit definieren.
  4. Sie können die Schnittstelle auch wie eine Klasse erweitern. Sie können die Schnittstelle in PHP mit dem Schlüsselwort extenses erweitern.
  5. Erweitern Sie mehrere Schnittstellen.
  6. Sie können nicht 2 Schnittstellen implementieren, wenn beide Funktionen mit demselben Namen gemeinsam nutzen. Es wird einen Fehler auslösen.

Beispielcode:

interface test{
    public function A($i);
    public function B($j = 20);
}

class xyz implements test{
    public function A($a){
        echo "CLASS A Value is ".$a;
    }
    public function B($b){
        echo "CLASS B Value is ".$b;
    }
}
$x = new xyz();
echo $x->A(11);
echo "<br/>";
echo $x->B(10);

2

Wir haben gesehen, dass abstrakte Klassen und Schnittstellen insofern ähnlich sind, als sie abstrakte Methoden bereitstellen, die in den untergeordneten Klassen implementiert werden müssen. Sie weisen jedoch noch folgende Unterschiede auf:

1. Schnittstellen können abstrakte Methoden und Konstanten enthalten, jedoch keine konkreten Methoden und Variablen.

2. Alle Methoden in der Schnittstelle müssen sich im Bereich der öffentlichen Sichtbarkeit befinden.

3. Eine Klasse kann mehr als eine Schnittstelle implementieren, während sie nur von einer abstrakten Klasse erben kann.

                                  interface                      abstract class
the code                     - abstract methods               - abstract methods
                             - constants                      - constants                  
                                                              - concrete methods
                                                              - concrete variables

access modifiers             
                             - public                         - public
                                                              - protected
                                                              - private
                                                                etc.
number of parents          The same class can implement
                           more than 1 interface              The child class can 
                                                              inherit only from 1 abstract class

Hoffe, dieser Wille hilft jedem zu verstehen!


2

Schnittstellen sind wie Ihre Gene.

Abstrakte Klassen sind wie deine eigentlichen Eltern.

Ihre Zwecke sind erblich bedingt, aber im Fall von abstrakten Klassen gegenüber Schnittstellen ist das, was vererbt wird, spezifischer.


2

Ich weiß nichts über andere Sprachen, was ist das Konzept der Schnittstelle dort. Aber für PHP werde ich mein Bestes geben, um es zu erklären. Seien Sie einfach geduldig und kommentieren Sie bitte, ob dies geholfen hat.

Eine Schnittstelle fungiert als "Verträge" und gibt an, was eine Reihe von Unterklassen tut, aber nicht, wie sie es tun.

Die Regel

  1. Eine Schnittstelle kann nicht instanziiert werden.

  2. Sie können keine Methode in einer Schnittstelle implementieren, dh sie enthält nur die Signatur der Methode, aber keine Details (body).

  3. Schnittstellen können Methoden und / oder Konstanten enthalten, jedoch keine Attribute. Schnittstellenkonstanten unterliegen denselben Einschränkungen wie Klassenkonstanten. Schnittstellenmethoden sind implizit abstrakt.

  4. Schnittstellen dürfen keine Konstruktoren oder Destruktoren deklarieren, da dies Implementierungsdetails auf Klassenebene sind.

  5. Alle Methoden in einer Schnittstelle müssen öffentlich sichtbar sein.

Nehmen wir nun ein Beispiel. Angenommen, wir haben zwei Spielzeuge: eines ist ein Hund und das andere ist eine Katze.

Wie wir wissen, bellt ein Hund und miaut eine Katze. Diese beiden haben dieselbe Sprechmethode, aber unterschiedliche Funktionen oder Implementierungen. Angenommen, wir geben dem Benutzer eine Fernbedienung mit einer Sprechtaste.

Wenn der Benutzer die Sprechtaste drückt, muss das Spielzeug sprechen, egal ob es sich um einen Hund oder eine Katze handelt.

Dies ist ein guter Fall, um eine Schnittstelle zu verwenden, keine abstrakte Klasse, da die Implementierungen unterschiedlich sind. Warum? Merken

Wenn Sie die untergeordneten Klassen durch Hinzufügen einer nicht abstrakten Methode unterstützen müssen, sollten Sie abstrakte Klassen verwenden. Andernfalls würden Sie Schnittstellen wählen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.