Anvendelse af grænseflader i OOP i PHP
Så vi har allerede konstateret, at grænseflader er en god måde at kontrollere, at alle nødvendige klassemetoder er implementeret.
Lad os se på et andet, mere praktisk, eksempel. Antag, at vi har en klasse, som vil gemme et array af objekter-figurer:
<?php
class FiguresCollection
{
private $figures = []; // array til figurer
}
?>
Lad os implementere metoden addFigure
i vores klasse for at tilføje objekter til samlingen:
<?php
class FiguresCollection
{
private $figures = [];
// Et objekt med en figur sendes som parameter:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
Det er indlysende, at vi regner med, at
parameteren for metoden addFigure vil
blive sendt som et objekt med en figur. Men der
er ingen kontrol over dette!
Lad os bruge en type-hint og
eksplicit angive typen af objekter som Figure:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
Lad os se nærmere på, hvad vi har gjort.
Hvis Figure var en virkelig eksisterende
klasse, kunne vi i metodens parameter
sende objekter af denne klasse, og også
dens arvinger.
Men for os er Figure en grænseflade.
I dette tilfælde betyder type-hintet, at
parameteren for metoden kun kan være
objekter af klasser, der implementerer vores grænseflade.
Lad os prøve at oprette et objekt af vores klasse og tilføje figurer til det:
<?php
$figuresCollection = new FiguresCollection;
// Tilføj et par kvadrater:
$figuresCollection->add(new Quadrate(2));
$figuresCollection->add(new Quadrate(3));
// Tilføj et par rektangler:
$figuresCollection->add(new Rectangle(2, 3));
$figuresCollection->add(new Rectangle(3, 4));
?>
Et forsøg på at tilføje et objekt af en hvilken som helst anden klasse vil føre til en fejl:
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // en anden klasse
$figuresCollection->add(new Test); // vil give en fejl
?>
Hvad giver en sådan kontrol os i praksis:
da alle figurer tilføjet til samlingen
implementerer grænsefladen Figure, kan vi
være sikre på, at hver af dem vil have metoden
getSquare og metoden
getPerimeter.
Måske vil der i fremtiden, udover kvadrat og rektangel,
opstå, for eksempel, en trekant. I
det tilfælde vil trekanten også have
metoderne getSquare og
getPerimeter.
I praksis giver dette os følgende: vi kan
i klassen FiguresCollection lave,
for eksempel, en metode getTotalSquare, der finder
den samlede areal af samlingens figurer. I denne metode
vil vi gennemgå arrayet af figurer i en løkke og
for hver figur kalde
metoden getSquare.
Da hver figur implementerer grænsefladen
Figure, kan vi være 100%
sikre på, at hver figur vil have
denne metode getSquare.
Så, her er implementeringen af metoden:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
// Find den samlede areal:
public function getTotalSquare()
{
$sum = 0;
foreach ($this->figures as $figure) {
$sum += $figure->getSquare(); // bruger metoden getSquare
}
return $sum;
}
}
?>
Uden at kigge på min kode, implementer en sådan
klasse FiguresCollection.
Tilføj til klassen FiguresCollection
en metode getTotalPerimeter for at finde
den samlede omkreds af alle figurer.