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 MySqlPerson
Klasse oder die MongoPerson
Klasse 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 IPersonService
Schnittstelle 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.