Používanie rozhraní v OOP v PHP
Takže sme už zistili, že rozhrania sú dobrý spôsob, ako kontrolovať, že sú implementované všetky potrebné metódy triedy.
Pozrime sa na ďalší, praktickejší príklad. Nech máme triedu, ktorá bude ukladať pole objektov-útvarov:
<?php
class FiguresCollection
{
private $figures = []; // pole pre útvary
}
?>
Implementujme v našej triede metódu addFigure
pre pridávanie objektov do kolekcie:
<?php
class FiguresCollection
{
private $figures = [];
// Parametrom sa odovzdáva objekt s útvarom:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
Je zrejmé, že počítame s tým, že
parametrom metódy addFigure bude
odovzdávaný objekt s útvarom. Avšak žiadna
kontrola za tým nie je!
Využime typovú nápovedu a
explicitne určme typ objektov ako Figure:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
Poďme sa pozrieť, čo sme vlastne urobili.
Ak by Figure bola skutočne existujúcou
triedou, tak do parametra metódy by sme mohli
odovzdať objekty tejto triedy, ako aj
jej potomkov.
My však máme Figure ako rozhranie.
V takom prípade typová nápoveda znamená, že
parametrom metódy môžu byť odovzdané len
objekty tried, ktoré implementujú naše rozhranie.
Skúsme vytvoriť objekt našej triedy a pridať do nej útvary:
<?php
$figuresCollection = new FiguresCollection;
// Pridajme pár štvorcov:
$figuresCollection->add(new Quadrate(2));
$figuresCollection->add(new Quadrate(3));
// Pridajme pár obdĺžnikov:
$figuresCollection->add(new Rectangle(2, 3));
$figuresCollection->add(new Rectangle(3, 4));
?>
Pokus pridať objekt akejkoľvek inej triedy povedie k chybe:
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // nejaká iná trieda
$figuresCollection->add(new Test); // vypíše chybu
?>
Čo nám v praxi dáva takáto kontrola:
keďže všetky útvary pridané do kolekcie
implementujú rozhranie Figure, môžeme
byť istí, že každý z nich bude mať metódu
getSquare a metódu
getPerimeter.
Je možné, že v budúcnosti okrem štvorca a obdĺžnika
príde napríklad aj trojuholník. V
tom prípade aj trojuholník bude mať
metódy getSquare a
getPerimeter.
V praxi nám to dáva nasledovné: môžeme
v triede FiguresCollection vytvoriť,
napríklad, metódu getTotalSquare, ktorá nájde
celkovú plochu útvarov kolekcie. V tejto metóde
budeme prechádzať cyklom pole útvarov a
každému útvaru volať
metódu getSquare.
Keďže každý útvar implementuje rozhranie
Figure, môžeme byť na 100%
istí, že každý útvar bude mať
túto metódu getSquare.
Takže, tu je implementácia metódy:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
// Nájdime celkovú plochu:
public function getTotalSquare()
{
$sum = 0;
foreach ($this->figures as $figure) {
$sum += $figure->getSquare(); // použijeme metódu getSquare
}
return $sum;
}
}
?>
Bez nahliadania do môjho kódu implementujte rovnakú
triedu FiguresCollection.
Pridajte do triedy FiguresCollection
metódu getTotalPerimeter na nájdenie
celkového obvodu všetkých útvarov.