# Применение интерфейсов в ООП на PHP

Итак, мы уже выяснили, что интерфейсы хороший способ контролировать то, что реализованы все необходимые методы класса.

Давайте рассмотрим еще один, более практический, пример. Пусть у нас есть класс, который будет хранить в себе массив объектов-фигур:

`<?php class FiguresCollection { private $figures = []; // массив для фигур } ?>`

Реализуем в нашем классе метод `addFigure` для добавления объектов в коллекцию:

`<?php class FiguresCollection { private $figures = []; // Параметром передается объект с фигурой: public function addFigure($figure) { $this->figures[] = $figure; } } ?>`

Очевидно, что мы рассчитываем на то, что параметром метода `addFigure` будет передаваться объект с фигурой. Однако за этим нет никакого контроля!

Давайте используем подсказку для типов и явно укажем тип объектов как `Figure`:

`<?php class FiguresCollection { private $figures = []; public function addFigure(Figure $figure) { $this->figures[] = $figure; } } ?>`

Давайте разберемся с тем, что мы сделали.

Если бы `Figure` был реально существующим классом то в параметр метода мы смогли бы передать объекты этого класса, а также и его наследников.

У нас, однако, `Figure` - это интерфейс. В таком случае подсказка обозначает то, что параметром метода могут быть переданы только объекты класса, реализующих наш интерфейс.

Давайте попробуем создать объект нашего класса и добавить в него фигуры:

`<?php $figuresCollection = new FiguresCollection; // Добавим парочку квадратов: $figuresCollection->add(new Quadrate(2)); $figuresCollection->add(new Quadrate(3)); // Добавим парочку прямоугольников: $figuresCollection->add(new Rectangle(2, 3)); $figuresCollection->add(new Rectangle(3, 4)); ?>`

Попытка добавить объект какого-либо другого класса приведет к ошибке:

`<?php $figuresCollection = new FiguresCollection; class Test {}; // какой-то другой класс $figuresCollection->add(new Test); // выдаст ошибку ?>`

Что на практике дает нам такой контроль: так как все фигуры, добавленные в коллекцию, реализуют интерфейс `Figure`, мы можем быть уверены, что у каждой из них будет метод `getSquare` и метод `getPerimeter`.

Возможно в дальнейшем кроме квадрата и прямоугольника появится, например, еще и треугольник. В этом случае и у треугольника также будут методы `getSquare` и `getPerimeter`.

На практике это дает нам следующее: мы можем в классе `FiguresCollection` сделать, к примеру, метод `getTotalSquare`, находящий полную площадь фигур коллекции. В этом методе мы будем перебирать циклом массив фигур и у каждой фигуры вызывать метод `getSquare`.

Так как каждая фигура реализует интерфейс `Figure`, мы можем быть на `100%` уверены в том, что у каждой фигуры будет этот метод `getSquare`.

Итак, вот реализация метода:

`<?php class FiguresCollection { private $figures = []; public function addFigure(Figure $figure) { $this->figures[] = $figure; } // Найдем полную площадь: public function getTotalSquare() { $sum = 0; foreach ($this->figures as $figure) { $sum += $figure->getSquare(); // используем метод getSquare } return $sum; } } ?>`

Не подсматривая в мой код реализуйте такой же класс `FiguresCollection`.

Добавьте в класс `FiguresCollection` метод `getTotalPerimeter` для нахождения суммарного периметра всех фигур.

←→
↑