Uporaba vmesnikov v OOP v PHP
Torej, že smo ugotovili, da so vmesniki dober način za nadzor nad tem, da so implementirane vse potrebne metode razreda.
Poglejmo še en, bolj praktičen, primer. Recimo, da imamo razred, ki bo shranjeval polje objektov-oblik:
<?php
class FiguresCollection
{
private $figures = []; // polje za oblike
}
?>
Implementirajmo v našem razredu metodo addFigure
za dodajanje objektov v zbirko:
<?php
class FiguresCollection
{
private $figures = [];
// Parameter se posreduje objekt z obliko:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
Očitno je, da računamo na to, da bo
parameter metode addFigure
posredovan objekt z obliko. Vendar za
tem ni nobenega nadzora!
Uporabimo namig za tipe in
izrecno navedimo tip objektov kot Figure:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
Razložimo, kaj smo naredili.
Če bi bil Figure dejansko obstoječ
razred, bi lahko v parameter metode posredovali
objekte tega razreda in tudi njegovih potomcev.
Pri nas pa je Figure vmesnik.
V tem primeru namig pomeni, da
lahko kot parameter metode posredujemo samo
objekte razreda, ki implementirajo naš vmesnik.
Poskusimo ustvariti objekt našega razreda in vanj dodati oblike:
<?php
$figuresCollection = new FiguresCollection;
// Dodajmo nekaj kvadratov:
$figuresCollection->add(new Quadrate(2));
$figuresCollection->add(new Quadrate(3));
// Dodajmo nekaj pravokotnikov:
$figuresCollection->add(new Rectangle(2, 3));
$figuresCollection->add(new Rectangle(3, 4));
?>
Poskus dodajanja objekta katerega koli drugega razreda bo povzročil napako:
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // kateri koli drug razred
$figuresCollection->add(new Test); // bo povzročilo napako
?>
Kaj nam tak nadzor daje v praksi:
ker vse oblike, dodane v zbirko,
implementirajo vmesnik Figure, lahko
smo prepričani, da bo imela vsaka od njih metodo
getSquare in metodo
getPerimeter.
Morda se bo v prihodnosti poleg kvadrata in pravokotnika
pojavil na primer še trikotnik. V
tem primeru bo tudi trikotnik imel
metodi getSquare in
getPerimeter.
V praksi nam to daje naslednje: lahko
v razredu FiguresCollection naredimo,
na primer, metodo getTotalSquare, ki najde
celotno površino vseh oblik v zbirki. V tej metodi
bomo s ciklom prebrali polje oblik in
pri vsaki obliki poklicali
metodo getSquare.
Ker vsaka oblika implementira vmesnik
Figure, smo lahko 100%
prepričani, da bo vsaka oblika imela
to metodo getSquare.
Torej, tu je implementacija metode:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
// Poiščimo skupno površino:
public function getTotalSquare()
{
$sum = 0;
foreach ($this->figures as $figure) {
$sum += $figure->getSquare(); // uporabimo metodo getSquare
}
return $sum;
}
}
?>
Ne gledaje v mojo kodo implementirajte enak
razred FiguresCollection.
Dodajte v razred FiguresCollection
metodo getTotalPerimeter za iskanje
skupnega obsega vseh oblik.