Tillämpning av gränssnitt i OOP i PHP
Så, vi har redan upptäckt att gränssnitt är ett bra sätt att kontrollera att alla nödvändiga klassmetoder är implementerade.
Låt oss titta på ett annat, mer praktiskt, exempel. Låt oss säga att vi har en klass som kommer att lagra en array av objekt-figurer:
<?php
class FiguresCollection
{
private $figures = []; // array för figurer
}
?>
Låt oss implementera metoden addFigure
i vår klass för att lägga till objekt i samlingen:
<?php
class FiguresCollection
{
private $figures = [];
// Ett objekt med en figur skickas som parameter:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
Uppenbarligen räknar vi med att
parametern för metoden addFigure kommer
att skicka ett objekt med en figur. Men det finns
ingen kontroll över detta!
Låt oss använda en typ-hint och
uttryckligen ange typen av objekt som Figure:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
Låt oss reda ut vad vi gjorde.
Om Figure var en faktiskt existerande
klass, skulle vi i metodens parameter kunna
skicka objekt av denna klass, och även
dess arvtagare.
Men för oss är Figure ett gränssnitt.
I detta fall betyder hinten att
endast objekt från klasser som implementerar vårt gränssnitt kan skickas som parameter till metoden.
Låt oss försöka skapa ett objekt av vår klass och lägga till figurer i den:
<?php
$figuresCollection = new FiguresCollection;
// Lägg till ett par kvadrater:
$figuresCollection->add(new Quadrate(2));
$figuresCollection->add(new Quadrate(3));
// Lägg till ett par rektanglar:
$figuresCollection->add(new Rectangle(2, 3));
$figuresCollection->add(new Rectangle(3, 4));
?>
Ett försök att lägga till ett objekt från någon annan klass kommer att leda till ett fel:
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // någon annan klass
$figuresCollection->add(new Test); // kommer att ge ett fel
?>
Vad ger oss en sådan kontroll i praktiken:
eftersom alla figurer som läggs till i samlingen
implementerar gränssnittet Figure, kan vi
vara säkra på att var och en av dem kommer att ha metoden
getSquare och metoden
getPerimeter.
I framtiden kan det förutom kvadrat och rektangel
dyka upp, till exempel, en triangel. I
detta fall kommer triangeln också att ha
metoderna getSquare och
getPerimeter.
I praktiken ger oss detta följande: vi kan
i klassen FiguresCollection skapa,
till exempel, en metod getTotalSquare som hittar
den totala arean av figurerna i samlingen. I denna metod
kommer vi att gå igenom arrayen av figurer i en loop och
för varje figur anropa
metoden getSquare.
Eftersom varje figur implementerar gränssnittet
Figure, kan vi vara 100%
säkra på att varje figur kommer att ha
denna metod getSquare.
Så, här är implementationen av metoden:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
// Hitta den totala arean:
public function getTotalSquare()
{
$sum = 0;
foreach ($this->figures as $figure) {
$sum += $figure->getSquare(); // använder metoden getSquare
}
return $sum;
}
}
?>
Utan att kolla på min kod, implementera en liknande
klass FiguresCollection.
Lägg till metoden getTotalPerimeter i klassen FiguresCollection
för att hitta
totala omkretsen av alla figurer.