Изучая предыдущие уроки о классах вы уже многое знаете и наверняка думаете, "ну что же еще придумали эти разработчики 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.
Добавить комментарий