Primena interfejsa u OOP-u u PHP-u
Dakle, već smo utvrdili da su interfejsi dobar način da kontrolišemo da li su implementirane sve potrebne metode klase.
Hajde da razmotrimo još jedan, praktičniji, primer. Pretpostavimo da imamo klasu koja će čuvati u sebi niz objekata-figura:
<?php
class FiguresCollection
{
private $figures = []; // niz za figure
}
?>
Implementirajmo u našoj klasi metodu addFigure
za dodavanje objekata u kolekciju:
<?php
class FiguresCollection
{
private $figures = [];
// Parametrom se prosleđuje objekat sa figurom:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
Očigledno je da računamo na to da će
parametrom metode addFigure biti
prosledjen objekat sa figurom. Međutim, za
tim nema nikakve kontrole!
Hajde da iskoristimo podsetnik za tipove i
eksplicitno navedemo tip objekata kao Figure:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
Hajde da razjasnimo šta smo uradili.
Da je Figure bio realno postojeći
klas, onda bismo u parametar metode mogli
prosledit objekte te klase, kao i
njegove naslednike.
Kod nas je, međutim, Figure interfejs.
U tom slučaju, podsetnik označava da
parametrom metode mogu biti prosledjeni samo
objekti klase koji implementiraju naš interfejs.
Pokušajmo da napravimo objekat naše klase i da u njega dodamo figure:
<?php
$figuresCollection = new FiguresCollection;
// Dodajmo par kvadrata:
$figuresCollection->add(new Quadrate(2));
$figuresCollection->add(new Quadrate(3));
// Dodajmo par pravougaonika:
$figuresCollection->add(new Rectangle(2, 3));
$figuresCollection->add(new Rectangle(3, 4));
?>
Pokušaj da se doda objekat neke druge klase će dovesti do greške:
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // neka druga klasa
$figuresCollection->add(new Test); // izbaciće grešku
?>
Šta nam u praksi daje takva kontrola:
pošto sve figure, dodate u kolekciju,
implementiraju interfejs Figure, možemo
biti sigurni da će svaka od njih imati metodu
getSquare i metodu
getPerimeter.
Moguće je da će se u budućnosti pored kvadrata i pravougaonika
pojaviti, na primer, još i trougao. U
tom slučaju će i trougao takođe imati
metode getSquare i
getPerimeter.
U praksi nam ovo daje sledeće: možemo
u klasi FiguresCollection napraviti,
na primer, metod getTotalSquare, koji pronalazi
ukupnu površinu figura kolekcije. U ovoj metodi
ćemo prolaziti kroz niz figura petljom i
svakoj figuri pozivati
metodu getSquare.
Pošto svaka figura implementira interfejs
Figure, možemo biti 100%
sigurni da će svaka figura imati
taj metod getSquare.
Dakle, evo implementacije metode:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
// Pronađimo ukupnu površinu:
public function getTotalSquare()
{
$sum = 0;
foreach ($this->figures as $figure) {
$sum += $figure->getSquare(); // koristimo metod getSquare
}
return $sum;
}
}
?>
Ne zavirujući u moj kod implementirajte takvu
istu klasu FiguresCollection.
Dodajte u klasu FiguresCollection
metod getTotalPerimeter za pronalaženje
ukupnog obima svih figura.