Bruk av grensesnitt i OOP i PHP
Så, vi har allerede funnet ut at grensesnitt er en god måte å kontrollere at alle nødvendige metoder i en klasse er implementert.
La oss se på et annet, mer praktisk, eksempel. La oss si at vi har en klasse som skal lagre en array med objekter-former:
<?php
class FiguresCollection
{
private $figures = []; // array for figurer
}
?>
La oss implementere metoden addFigure
i vår klasse for å legge til objekter i samlingen:
<?php
class FiguresCollection
{
private $figures = [];
// Et objekt med en figur sendes som parameter:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
Det er åpenbart at vi regner med at
parameteren til metoden addFigure vil
være et objekt med en figur. Men det er
ingen kontroll for dette!
La oss bruke typehinting og
eksplisitt angi typen av objekter som Figure:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
La oss finne ut av hva vi har gjort.
Hvis Figure var en virkelig eksisterende
klasse, kunne vi i metodens parameter
sende objekter av denne klassen, og også
av dens arvinger.
Imidlertid er Figure et grensesnitt for oss.
I dette tilfellet betyr typehinting at
som parameter til metoden kan kun
objekter av klasser som implementerer vårt grensesnitt sendes.
La oss prøve å opprette et objekt av vår klasse og legge til figurer i den:
<?php
$figuresCollection = new FiguresCollection;
// La oss legge til et par kvadrater:
$figuresCollection->add(new Quadrate(2));
$figuresCollection->add(new Quadrate(3));
// La oss legge til et par rektangler:
$figuresCollection->add(new Rectangle(2, 3));
$figuresCollection->add(new Rectangle(3, 4));
?>
Et forsøk på å legge til et objekt av en hvilken som helst annen klasse vil føre til en feil:
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // en annen klasse
$figuresCollection->add(new Test); // vil gi en feil
?>
Hva gir oss en slik kontroll i praksis:
siden alle figurer som er lagt til i samlingen,
implementerer grensesnittet Figure, kan vi
være sikre på at hver av dem vil ha metoden
getSquare og metoden
getPerimeter.
Det er mulig at det i fremtiden, i tillegg til kvadrat og rektangel,
dukker opp, for eksempel, en trekant. I
dette tilfellet vil også trekanten ha
metodene getSquare og
getPerimeter.
I praksis gir dette oss følgende: vi kan
i klassen FiguresCollection lage,
for eksempel, en metode getTotalSquare som finner
den totale arealen av figurene i samlingen. I denne metoden
vil vi gå gjennom arrayen med figurer i en løkke og
for hver figur kalle
metoden getSquare.
Siden hver figur implementerer grensesnittet
Figure, kan vi være 100%
sikre på at hver figur vil ha
denne metoden getSquare.
Så, her er implementeringen av metoden:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
// La oss finne det totale arealet:
public function getTotalSquare()
{
$sum = 0;
foreach ($this->figures as $figure) {
$sum += $figure->getSquare(); // bruker metoden getSquare
}
return $sum;
}
}
?>
Uten å kikke på koden min, implementer en slik
klasse FiguresCollection.
Legg til i klassen FiguresCollection
en metode getTotalPerimeter for å finne
total omkrets av alle figurer.