Interfészek alkalmazása az OOP-ban PHP-ben
Tehát már megállapítottuk, hogy az interfészek jó módja annak, hogy ellenőrizzük, egy osztály minden szükséges metódusa megvalósult-e.
Nézzünk meg egy még gyakorlatiasabb példát. Tegyük fel, van egy osztályunk, ami alakzat objektumok tömbjét tárolja:
<?php
class FiguresCollection
{
private $figures = []; // tömb az alakzatoknak
}
?>
Valósítsuk meg osztályunkban a addFigure metódust
objektumok gyűjteménybe való hozzáadásához:
<?php
class FiguresCollection
{
private $figures = [];
// Paraméterként egy alakzat objektumot adunk át:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
Nyilvánvaló, hogy arra számítunk, hogy a addFigure metódus
paramétereként egy alakzat objektum lesz átadva. Azonban erre nincs semmiféle ellenőrzés!
Használjunk típus hint-et és explicit adjuk meg az objektumok típusát Figure-ként:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
Értsük meg, mit tettünk.
Ha a Figure egy valóban létező osztály lenne, akkor a metódus paraméterébe
át tudnánk adni az adott osztály objektumait, valamint annak leszármazottait is.
Nálunk azonban a Figure egy interfész.
Ilyen esetben a hint azt jelenti, hogy a metódus paraméterébe
csak azon osztályok objektumai adhatók át, amelyek megvalósítják az interfészünket.
Próbáljunk meg létrehozni egy objektumot az osztályunkból és adjunk hozzá alakzatokat:
<?php
$figuresCollection = new FiguresCollection;
// Adjunk hozzá pár négyzetet:
$figuresCollection->add(new Quadrate(2));
$figuresCollection->add(new Quadrate(3));
// Adjunk hozzá pár téglalapot:
$figuresCollection->add(new Rectangle(2, 3));
$figuresCollection->add(new Rectangle(3, 4));
?>
Bármely más osztály objektumának hozzáadása hibához fog vezetni:
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // valami más osztály
$figuresCollection->add(new Test); // hibát fog adni
?>
Mit ad gyakorlatilag nekünk ez az ellenőrzés:
mivel a gyűjteménybe hozzáadott összes alakzat
megvalósítja a Figure interfészt, biztosak lehetünk benne,
hogy mindegyikük rendelkezik a getSquare metódussal
és a getPerimeter metódussal.
Lehetséges, hogy a jövőben a négyzet és téglalap mellett
megjelenik például egy háromszög is. Ebben
az esetben a háromszögnek is lesznek
getSquare és getPerimeter metódusai.
Gyakorlatilag ez a következőt jelenti: a
FiguresCollection osztályban készíthetünk
például egy getTotalSquare metódust, amely
megtalálja a gyűjtemény alakzatainak teljes területét. Ebben a metódusban
bejárjuk ciklussal az alakzatok tömbjét és
minden egyes alakzaton meghívjuk a
getSquare metódust.
Mivel minden alakzat megvalósítja a Figure
interfészt, 100%-ig biztosak lehetünk
abban, hogy minden alakzat rendelkezik
ezzel a getSquare metódussal.
Tehát itt a metódus megvalósítása:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
// Keressük meg a teljes területet:
public function getTotalSquare()
{
$sum = 0;
foreach ($this->figures as $figure) {
$sum += $figure->getSquare(); // a getSquare metódust használjuk
}
return $sum;
}
}
?>
Ne kukucskálj az én kódom mögé, valósítsd meg ugyanezt
a FiguresCollection osztályt.
Add hozzá a FiguresCollection osztályhoz
a getTotalPerimeter metódust az összes alakzat
összperiméterének megtalálásához.