Классы и объекты в PHP: Абстрактные классы и зачем они нужны. Часть 6

Классы и объекты в PHP: Абстрактные классы и зачем они нужны. Часть 6

Изучая предыдущие уроки о классах вы уже многое знаете и наверняка думаете, "ну что же еще придумали эти разработчики PHP". И вы правы! Есть такая вещь, как абстрактные классы. Рассмотрим их подробнее.

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

Абстрактный класс нужен когда требуется создать семейство классов, у которых есть что-то общее. 

Представьте, что у вас есть магазин (абстрактный класс), а в нем разные типы товаров (обычные классы): велосипеды и машины. Так вот, у каждого типа товара есть что-то общее, например, их можно продать (абстрактный метод). Но к примеру, велосипеды вы можете продать по формуле с одной скидкой, а автомобили по другой. Таким образом, классы велосипед и автомобиль будут использовать один и тот же метод (продать), но функционал будет разный у каждого. А "объединит" это все как раз абстрактный класс.

Создадим такой абстрактный класс:

abstract class Magazin {
protected $procent = 5;
public function procent() { return $this->procent; } /* Обычный метод, который доступен всем дочерним классам */
abstract public function write($cena); /* Абстрактный метод должен быть определён в дочернем классе */
}

А теперь теория:

Абстрактный класс - это класс, в котором можно как и в обычном создавать свойства и методы, но при попытке создать объект этого класса, появится ошибка.

В абстрактном классе можно создавать абстрактные методы. Изначально они не определены (неизвестно, что будет внутри них). Но при наследовании абстрактного класса обычным - вы должны написать функционал всех абстрактных методов и передать все переменные, которые заданы в абстрактных методах. При этом надо соблюдать уровень доступа - он не может быть более строгим, чем в абстрактном методе. Например, если абстрактный метод объявлен как protected, то реализация этого метода должна быть либо protected либо public, но не private

Теперь создадим классы авто и велосипеда:

class ProductAuto extends Magazin {
function write($cena) { return $cena*(1-$this->procent()*0.01); }
}
class ProductVelo extends Magazin {
function write($cena) { return $cena*(1-$this->procent()*0.01*2); }
}

Как вы видите в обоих классах мы наследуем данные от абстрактного класса Magazin и используем его метод procent(). Также в обоих классах мы задали метод write($cena), в которых идет подсчет цены товара по разным формулам для велосипеда 10%, для авто 5%.

Если бы мы создали пустой класс, без метода write($cena), то появилась бы справедливая ошибка: Fatal error: Class ProductAuto contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Magazin::write). Означающая, что дочерний класс должен содержать метод write(), который определен в абстрактном суперклассе.

Если бы мы создали класс с методом write(), но не передали бы в него значение $cena, то появилась бы такая ошибка: Fatal error: Declaration of ProductAuto::write() must be compatible with that of Magazin::write(). Означающая, что мы передали не все обязательные переменные, которые заданы в абстрактном суперклассе.

Выведем значения:

$ProductAuto = new ProductAuto();
echo 'Цена со скидкой на авто (5%): '.$ProductAuto->write(5000);
$ProductVelo = new ProductVelo();
echo '<br>Цена со скидкой на велосипед (5%*2): '.$ProductVelo->write(1000);

Таким образом, абстрактные классы позволяют объединять обычные классы и легко использовать свойства и методы самого абстрактного класса, а также быстро создавать/использовать абстрактные методы в наследуемых классах (при этом функционал этих методов может кардинально различаться).

В следующем уроке, рассмотрим интерфейсы в PHP.

| | Классы и объекты в PHP: Абстрактные классы и зачем они нужны. Часть 6 | Изучая предыдущие уроки о классах вы уже многое знаете и наверняка думаете, "ну что же еще придумали эти разработчики PHP". И вы правы! Есть такая вещ | http://blogprogram.ru/wp-content/uploads/2017/06/696-131x131.jpg