Wielokrotne interfejsy w OOP w PHP
W PHP nie ma wielokrotnego dziedziczenia - każda
klasa może mieć tylko jednego rodzica.
Z interfejsami sprawa wygląda jednak inaczej:
każda klasa może implementować dowolną liczbę
interfejsów. Aby to zrobić, nazwy interfejsów
należy wymienić po przecinku po słowie kluczowym
implements.
Jest to kolejna różnica między interfejsami a klasami abstrakcyjnymi - można implementować wiele interfejsów, ale nie można dziedziczyć po kilku klasach abstrakcyjnych.
Wypróbujmy to w praktyce. Załóżmy, że oprócz
interfejsu iFigure mamy również
interfejs iTetragon.
Metody tego interfejsu będą implementowane przez
klasy Quadrate i Rectangle,
ponieważ mają one 4 boki, ale nie przez klasę
Disk.
Załóżmy, że interfejs iTetragon opisuje
gettery dla wszystkich czterech boków
czworoboku:
<?php
interface iTetragon
{
public function getA();
public function getB();
public function getC();
public function getD();
}
?>
Załóżmy również, że mamy interfejs iFigure,
który tworzyliśmy wcześniej:
<?php
interface iFigure
{
public function getSquare();
public function getPerimeter();
}
?>
Sprawmy, aby klasa Quadrate
implementowała dwa interfejsy. W tym celu wymieńmy
oba interfejsy po przecinku po słowie kluczowym
implements:
<?php
class Quadrate implements iFigure, iTetragon
{
// tutaj będzie implementacja
}
?>
Rozbudujmy teraz naszą klasę Quadrate,
tak aby implementowała interfejs iTetragon.
Oczywiste jest, że nasz kwadrat jest szczególnym
przypadkiem czworoboku, ponieważ u kwadratu
wszystkie boki są równe. Dlatego wszystkie nowe metody
będą zwracać to samo - szerokość kwadratu:
<?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;
}
}
?>
Oczywiście, w prostokącie nie wszystkie
boki są już identyczne, a tylko przeciwległe.
W tym przypadku nowe metody będą się nieco
różnić. No, a w jakimś trapezie
w ogóle wszystkie 4 boki będą inne.
Niemniej jednak, nie ma znaczenia, jaką figurę będziemy rozważać - ważne, że wszystkie te figury będą miały opisane metody (nawet jeśli niektóre figury są szczególnymi przypadkami) i działać będą w jednolity sposób.
Spraw, aby klasa Rectangle
również implementowała dwa interfejsy: i iFigure,
i iTetragon.
Stwórz interfejs iCircle z metodami
getRadius i getDiameter.
Spraw, aby klasa Disk również
implementowała dwa interfejsy: i iFigure,
i iCircle.