Rajapintojen käyttö OOP:ssa PHP:ssä
Olemme jo todenneet, että rajapinnat ovat hyvä tapa hallita, että kaikki tarvittavat luokan metodit on toteutettu.
Tarkastellaan toista, käytännönläheisempää esimerkkiä. Oletetaan, että meillä on luokka, joka sisältää taulukon kuvio-olioita:
<?php
class FiguresCollection
{
private $figures = []; // taulukko kuvioille
}
?>
Toteutetaan luokkaamme metodi addFigure
olioiden lisäämiseksi kokoelmaan:
<?php
class FiguresCollection
{
private $figures = [];
// Parametrina välitetään kuvio-objekti:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
On ilmeistä, että laskemme sen varaan, että
metodin addFigure parametriksi
annetaan kuvio-objekti. Tästä ei kuitenkaan ole minkäänlaista valvontaa!
Käytetään tyyppivihjettä ja
määritellään eksplisiittisesti objektien tyypiksi Figure:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
Selvitetään, mitä teimme.
Jos Figure olisi oikeasti olemassa oleva
luokka, voisimme parametrille antaa tämän luokan olioita sekä sen perijöitä.
Meillä kuitenkin Figure on rajapinta.
Tässä tapauksessa tyyppivihje tarkoittaa, että
metodin parametriksi voidaan antaa vain
luokan olioita, jotka toteuttavat rajapintamme.
Yritetään luoda luokkamme olio ja lisätä siihen kuvioita:
<?php
$figuresCollection = new FiguresCollection;
// Lisätään pari neliötä:
$figuresCollection->add(new Quadrate(2));
$figuresCollection->add(new Quadrate(3));
// Lisätään pari suorakulmiota:
$figuresCollection->add(new Rectangle(2, 3));
$figuresCollection->add(new Rectangle(3, 4));
?>
Yritys lisätä minkä tahansa muun luokan olio johtaa virheeseen:
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // jokin toinen luokka
$figuresCollection->add(new Test); // antaa virheen
?>
Mitä tällainen valvonta käytännössä antaa meille:
koska kaikki kokoelmaan lisätyt kuviot
toteuttavat rajapinnan Figure, voimme
olla varmoja, että jokaisella niistä on metodi
getSquare ja metodi
getPerimeter.
Mahdollisesti tulevaisuudessa neliön ja suorakulmion lisäksi
ilmestyy esimerkiksi kolmiokin. Tässä
tapauksessa myös kolmiolla on
metodit getSquare ja
getPerimeter.
Käytännössä tämä antaa meille seuraavan: voimme
luokassa FiguresCollection tehdä
esimerkiksi metodin getTotalSquare, joka löytää
kuvioiden kokonaispinta-alan. Tässä metodissa
käymme läpi kuvioiden taulukon silmukalla ja
kutsumme jokaisen kuvion kohdalla
metodia getSquare.
Koska jokainen kuvio toteuttaa rajapinnan
Figure, voimme olla 100%
varmoja siitä, että jokaisella kuvioolla on
tämä metodi getSquare.
Esitetään metodin toteutus:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
// Etsitään kokonaispinta-ala:
public function getTotalSquare()
{
$sum = 0;
foreach ($this->figures as $figure) {
$sum += $figure->getSquare(); // käytetään getSquare-metodia
}
return $sum;
}
}
?>
Älä kurkkaa koodiini, vaan toteuta sama
luokka FiguresCollection.
Lisää luokkaan FiguresCollection
metodi getTotalPerimeter kaikkien kuvioiden
kokonaiskehän löytämiseksi.