Più interfacce in OOP in PHP
In PHP non c'è ereditarietà multipla - ogni
classe può avere un solo genitore.
Con le interfacce, tuttavia, le cose sono diverse:
ogni classe può implementare qualsiasi numero
di interfacce. Per fare ciò, i nomi delle interfacce
devono essere elencati separati da virgola dopo la parola chiave
implements.
Questo mostra un'altra differenza tra interfacce e classi astratte - è possibile implementare molte interfacce, ma non è possibile ereditare più classi astratte.
Proviamo nella pratica. Supponiamo che oltre
all'interfaccia iFigure abbiamo anche
l'interfaccia iTetragon.
I metodi di questa interfaccia saranno implementati
dalle classi Quadrate e Rectangle,
poiché hanno 4 lati, ma non dalla classe
Disk.
Supponiamo che l'interfaccia iTetragon descriva
i getter per tutti e quattro i lati
del quadrilatero:
<?php
interface iTetragon
{
public function getA();
public function getB();
public function getC();
public function getD();
}
?>
Supponiamo inoltre di avere l'interfaccia iFigure,
che abbiamo già creato in precedenza:
<?php
interface iFigure
{
public function getSquare();
public function getPerimeter();
}
?>
Facciamo in modo che la classe Quadrate
implementi due interfacce. Per fare questo elenchiamo
entrambe le interfacce separate da virgola dopo la parola chiave
implements:
<?php
class Quadrate implements iFigure, iTetragon
{
// qui ci sarà l'implementazione
}
?>
Ora modifichiamo la nostra classe Quadrate
in modo che implementi l'interfaccia iTetragon.
È chiaro che il nostro quadrato è un caso degenere
di quadrilatero, poiché in un quadrato
tutti i lati sono uguali. Pertanto tutti i nuovi metodi
restituiranno la stessa cosa - la larghezza del quadrato:
<?php
class Quadrate implements iFigure, iTetragon
{
private $a;
public function __construct($a)
{
$this->a = $a;
}
public function getA()
{
return $this->a;
}
public function getB()
{
return $this->a;
}
public function getC()
{
return $this->a;
}
public function getD()
{
return $this->a;
}
public function getSquare()
{
return $this->a * $this->a;
}
public function getPerimeter()
{
return 4 * $this->a;
}
}
?>
È ovvio che in un rettangolo non tutti
i lati sono uguali, ma solo quelli opposti.
In questo caso i nuovi metodi saranno leggermente
diversi. E, in un trapezio qualsiasi,
tutti e 4 i lati saranno diversi.
Tuttavia, non importa quale figura considereremo - è importante che tutte queste figure abbiano i metodi descritti (anche se alcune figure sono degeneri) e funzionino in modo uniforme.
Fate in modo che anche la classe Rectangle
implementi due interfacce: sia iFigure,
che iTetragon.
Create un'interfaccia iCircle con i metodi
getRadius e getDiameter.
Fate in modo che anche la classe Disk
implementi due interfacce: sia iFigure,
che iCircle.