Anwendung von Schnittstellen in OOP in PHP
Wir haben also bereits festgestellt, dass Schnittstellen ein guter Weg sind, zu kontrollieren, dass alle notwendigen Methoden einer Klasse implementiert sind.
Lassen Sie uns ein weiteres, praktischeres Beispiel betrachten. Nehmen wir an, wir haben eine Klasse, die ein Array von Objekten-Figuren speichern wird:
<?php
class FiguresCollection
{
private $figures = []; // Array für Figuren
}
?>
Implementieren wir in unserer Klasse die Methode addFigure
zum Hinzufügen von Objekten zur Sammlung:
<?php
class FiguresCollection
{
private $figures = [];
// Ein Objekt mit einer Figur wird als Parameter übergeben:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
Offensichtlich gehen wir davon aus, dass
dem Methodenparameter addFigure
ein Objekt mit einer Figur übergeben wird.
Allerdings gibt es dafür keine Kontrolle!
Lassen Sie uns einen Typ-Hinweis verwenden und
den Typ der Objekte explizit als Figure angeben:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
Lassen Sie uns klären, was wir getan haben.
Wenn Figure eine tatsächlich existierende
Klasse wäre, dann könnten wir dem Methodenparameter
Objekte dieser Klasse sowie ihrer Erben übergeben.
Bei uns ist Figure jedoch ein Interface.
In diesem Fall bedeutet der Typ-Hinweis, dass
dem Methodenparameter nur Objekte von Klassen
übergeben werden können, die unser Interface implementieren.
Versuchen wir, ein Objekt unserer Klasse zu erstellen und ihm Figuren hinzuzufügen:
<?php
$figuresCollection = new FiguresCollection;
// Fügen wir ein paar Quadrate hinzu:
$figuresCollection->add(new Quadrate(2));
$figuresCollection->add(new Quadrate(3));
// Fügen wir ein paar Rechtecke hinzu:
$figuresCollection->add(new Rectangle(2, 3));
$figuresCollection->add(new Rectangle(3, 4));
?>
Der Versuch, ein Objekt einer beliebigen anderen Klasse hinzuzufügen, führt zu einem Fehler:
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // eine andere Klasse
$figuresCollection->add(new Test); // wird einen Fehler ausgeben
?>
Was uns diese Kontrolle in der Praxis bringt:
Da alle Figuren, die der Sammlung hinzugefügt werden,
das Interface Figure implementieren, können wir
sicher sein, dass jede von ihnen die Methode
getSquare und die Methode
getPerimeter haben wird.
Möglicherweise erscheint in Zukunft neben dem Quadrat und dem Rechteck
noch ein Dreieck. In
diesem Fall wird auch das Dreieck die
Methoden getSquare und
getPerimeter haben.
In der Praxis bedeutet dies für uns Folgendes: Wir können
in der Klasse FiguresCollection beispielsweise
eine Methode getTotalSquare erstellen, die die
gesamte Fläche der Figuren in der Sammlung ermittelt. In dieser Methode
werden wir die Figuren in einer Schleife durchlaufen und
jede Figur die Methode getSquare aufrufen lassen.
Da jede Figur das Interface
Figure implementiert, können wir uns zu 100%
sicher sein, dass jede Figur diese
Methode getSquare haben wird.
Hier also die Implementierung der Methode:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
// Finden wir die Gesamtfläche:
public function getTotalSquare()
{
$sum = 0;
foreach ($this->figures as $figure) {
$sum += $figure->getSquare(); // verwenden die Methode getSquare
}
return $sum;
}
}
?>
Implementieren Sie dieselbe Klasse FiguresCollection,
ohne in meinen Code zu schauen.
Fügen Sie der Klasse FiguresCollection
die Methode getTotalPerimeter hinzu, um den
gesamten Umfang aller Figuren zu ermitteln.