Application des interfaces en POO en PHP
Ainsi, nous avons déjà établi que les interfaces sont un bon moyen de contrôler que toutes les méthodes nécessaires d'une classe sont implémentées.
Prenons un autre exemple, plus pratique. Supposons que nous ayons une classe qui va stocker un tableau d'objets-figures :
<?php
class FiguresCollection
{
private $figures = []; // tableau pour les figures
}
?>
Implémentons dans notre classe la méthode addFigure
pour ajouter des objets à la collection :
<?php
class FiguresCollection
{
private $figures = [];
// Un objet de figure est passé en paramètre :
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
Il est évident que nous comptons sur le fait
qu'un objet de figure sera passé en paramètre
de la méthode addFigure. Cependant, il n'y a
aucun contrôle là-dessus !
Utilisons une indication de type et
spécifions explicitement le type des objets comme Figure :
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
Analysons ce que nous avons fait.
Si Figure était une classe existante,
nous pourrions passer en paramètre de la méthode
des objets de cette classe, ainsi que
ses classes dérivées.
Chez nous, cependant, Figure est une interface.
Dans ce cas, l'indication signifie que
seuls les objets de classes implémentant notre interface
peuvent être passés en paramètre de la méthode.
Essayons de créer un objet de notre classe et d'y ajouter des figures :
<?php
$figuresCollection = new FiguresCollection;
// Ajoutons quelques carrés :
$figuresCollection->add(new Quadrate(2));
$figuresCollection->add(new Quadrate(3));
// Ajoutons quelques rectangles :
$figuresCollection->add(new Rectangle(2, 3));
$figuresCollection->add(new Rectangle(3, 4));
?>
Toute tentative d'ajouter un objet d'une autre classe entraînera une erreur :
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // une autre classe
$figuresCollection->add(new Test); // générera une erreur
?>
Ce que ce contrôle nous apporte en pratique :
étant donné que toutes les figures ajoutées à la collection
implémentent l'interface Figure, nous pouvons
être sûrs que chacune d'elles aura la méthode
getSquare et la méthode
getPerimeter.
Il est possible qu'à l'avenir, en plus du carré et du rectangle,
apparaisse, par exemple, un triangle. Dans
ce cas, le triangle aura également
les méthodes getSquare et
getPerimeter.
En pratique, cela nous donne ceci : nous pouvons
dans la classe FiguresCollection créer,
par exemple, une méthode getTotalSquare, trouvant
la surface totale des figures de la collection. Dans cette méthode
nous allons parcourir en boucle le tableau de figures et
pour chaque figure appeler
la méthode getSquare.
Comme chaque figure implémente l'interface
Figure, nous pouvons être sûrs à 100%
que chaque figure aura
cette méthode getSquare.
Ainsi, voici l'implémentation de la méthode :
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
// Trouvons la surface totale :
public function getTotalSquare()
{
$sum = 0;
foreach ($this->figures as $figure) {
$sum += $figure->getSquare(); // utilisons la méthode getSquare
}
return $sum;
}
}
?>
Sans regarder mon code, implémentez la même
classe FiguresCollection.
Ajoutez à la classe FiguresCollection
la méthode getTotalPerimeter pour trouver
le périmètre total de toutes les figures.