Použití rozhraní v OOP v PHP
Takže jsme již zjistili, že rozhraní jsou dobrý způsob, jak kontrolovat, že jsou implementovány všechny potřebné metody třídy.
Pojďme se podívat na další, více praktický, příklad. Předpokládejme, že máme třídu, která bude ukládat pole objektů-útvarů:
<?php
class FiguresCollection
{
private $figures = []; // pole pro útvary
}
?>
Implementujme v naší třídě metodu addFigure
pro přidávání objektů do kolekce:
<?php
class FiguresCollection
{
private $figures = [];
// Parametrem se předává objekt s útvarem:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
Je zřejmé, že počítáme s tím, že
parametrem metody addFigure bude
předáván objekt s útvarem. Ale nad tím
není žádná kontrola!
Použijme nápovědu pro typy a
explicitně určeme typ objektů jako Figure:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
Pojďme se podívat na to, co jsme udělali.
Kdyby Figure byla skutečně existující
třídou, pak bychom do parametru metody mohli
předat objekty této třídy a také
její potomky.
U nás je však Figure rozhraní.
V takovém případě nápověda znamená, že
parametrem metody mohou být předány pouze
objekty třídy, které implementují naše rozhraní.
Zkusme vytvořit objekt naší třídy a přidat do něj útvary:
<?php
$figuresCollection = new FiguresCollection;
// Přidáme pár čtverců:
$figuresCollection->add(new Quadrate(2));
$figuresCollection->add(new Quadrate(3));
// Přidáme pár obdélníků:
$figuresCollection->add(new Rectangle(2, 3));
$figuresCollection->add(new Rectangle(3, 4));
?>
Pokus o přidání objektu jakékoli jiné třídy povede k chybě:
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // nějaká jiná třída
$figuresCollection->add(new Test); // vypíše chybu
?>
Co nám v praxi dává taková kontrola:
protože všechny útvary přidané do kolekce
implementují rozhraní Figure, můžeme
být si jisti, že každá z nich bude mít metodu
getSquare a metodu
getPerimeter.
Je možné, že v budoucnu kromě čtverce a obdélníku
se objeví například ještě trojúhelník. V
tomto případě bude i trojúhelník mít
metody getSquare a
getPerimeter.
V praxi nám to dává následující: můžeme
v třídě FiguresCollection vytvořit,
například metodu getTotalSquare, která najde
celkovou plochu útvarů kolekce. V této metodě
budeme cyklem procházet pole útvarů a
u každého útvaru volat
metodu getSquare.
Protože každý útvar implementuje rozhraní
Figure, můžeme být na 100%
jisti tím, že každý útvar bude mít
tuto metodu getSquare.
Takže, zde je implementace metody:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
// Najdeme celkovou plochu:
public function getTotalSquare()
{
$sum = 0;
foreach ($this->figures as $figure) {
$sum += $figure->getSquare(); // použijeme metodu getSquare
}
return $sum;
}
}
?>
Bez nahlížení do mého kódu implementujte stejnou
třídu FiguresCollection.
Přidejte do třídy FiguresCollection
metodu getTotalPerimeter pro nalezení
celkového obvodu všech útvarů.