Несколько интерфейсов в ООП на PHP
В PHP нет множественного наследования - каждый
класс может иметь только одного родителя.
С интерфейсами дело, однако, обстоит по другому:
каждый класс может реализовывать любое количество
интерфейсов. Для этого имена интерфейсов
нужно перечислить через запятую после ключевого
слова implements
.
В этом проявляется еще одно отличие интерфейсов от абстрактных классов - можно реализовывать много интерфейсов, но унаследовать несколько абстрактных классов нельзя.
Давайте попробуем на практике. Пусть кроме
интерфейса iFigure
у нас также есть
интерфейс iTetragon
(четырехугольник).
Методы этого интерфейса будут реализовывать
классы Quadrate
и Rectangle
,
так как у них 4
стороны, но не класс
Disk
.
Пусть интерфейс iTetragon
описывает
геттеры для всех четырех сторон четырехугольника:
<?php
interface iTetragon
{
public function getA();
public function getB();
public function getC();
public function getD();
}
?>
Пусть также у нас есть интерфейс iFigure
,
который мы уже делали ранее:
<?php
interface iFigure
{
public function getSquare();
public function getPerimeter();
}
?>
Сделаем так, чтобы класс Quadrate
реализовывал два интерфейса. Для этого перечислим
оба интерфейса через запятую после ключевого
слова implements
:
<?php
class Quadrate implements iFigure, iTetragon
{
// тут будет реализация
}
?>
Доработаем теперь наш класс Quadrate
,
чтобы он реализовывал интерфейс iTetragon
.
Понятно, что наш квадрат является вырожденным
случаем четырехугольника, ведь у квадрата
все стороны равны. Поэтому все новые методы
будут возвращать одно и тоже - ширину квадрата:
<?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;
}
}
?>
Очевидно, что в прямоугольнике уже не все
стороны одинаковы, а только противоположные.
В этом случае новые методы станут немного
отличаться. Ну, и в какой-нибудь трапеции
вообще все 4
стороны будут разные.
Однако, не имеет значения, что за фигуру мы будем рассматривать - важно, что все эти фигуры будут иметь описанные методы (пусть некоторые фигуры и вырожденные) и работать однотипно.
Сделайте так, чтобы класс Rectangle
также реализовывал два интерфейса: и iFigure
,
и iTetragon
.
Сделайте интерфейс iCircle
с методами
getRadius
и getDiameter
.
Сделайте так, чтобы класс Disk
также
реализовывал два интерфейса: и iFigure
,
и iCircle
.