Изучаем абстрактные классы в PHP

Представьте, как было бы круто, если бы в интерфейсе можно было бы не только объявить методы, которые нужно реализовать, но и добавить некоторую реализацию. Например, определить какой-нибудь метод, у которого будет какая-то логика. Для этого в PHP есть абстрактные классы.

Выглядит определение абстрактного класса следующим образом:

abstract class AbstractClass
{
    // тело абстрактного класса
}

Давайте попробуем создать объект этого класса:

abstract class AbstractClass
{
    // тело абстрактного класса
}

$object = new AbstractClass();

Мы получим ошибку.
ошибка при создании объекта абстрактного класса

Создать объект абстрактного класса нельзя – от него можно только наследоваться. Примерно как с интерфейсами – их мы можем только реализовывать в других классах.

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

abstract class AbstractClass
{
    abstract public function getValue();
}

Но он также может содержать и обычные методы, которые будут содержать вполне себе реальную бизнес-логику. Пример:

abstract class AbstractClass
{
    abstract public function getValue();

    public function printValue()
    {
        echo 'Значение: ' . $this->getValue();
    }
}

То есть в классах-наследниках будет доступен уже реализованный метод printValue(), который без проблем можно переопределить. Он вызывает метод getValue(), который в самом классе пока не реализован, но мы можем его использовать в других методах.

Дочерние классы будут обязаны реализовать метод getValue(). Давайте опишем класс-наследник от этого абстрактного класса.

abstract class AbstractClass
{
    abstract public function getValue();

    public function printValue()
    {
        echo 'Значение: ' . $this->getValue();
    }
}

class ClassA extends AbstractClass
{

}

Такой код вызовет ошибку – класс ClassA не реализовал в себе метод getValue().

Ошибка из-за нереализованности абстрактного метода

Давайте это исправим.

abstract class AbstractClass
{
    abstract public function getValue();

    public function printValue()
    {
        echo 'Значение: ' . $this->getValue();
    }
}

class ClassA extends AbstractClass
{
    private $value;

    public function __construct(string $value)
    {
        $this->value = $value;
    }

    public function getValue()
    {
        return $this->value;
    }
}

$objectA = new ClassA('kek');
$objectA->printValue();

Этот код вполне нормально отработает, и выведет на экран “Значение: kek”.

loader
Домашнее задание

Создайте абстрактный класс Human.

abstract class HumanAbstract
{
    private $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    public function getName(): string
    {
        return $this->name;
    }

    abstract public function getGreetings(): string;
    abstract public function getMyNameIs(): string;

    public function introduceYourself(): string
    {
        return $this->getGreetings() . '! ' . $this->getMyNameIs() . ' ' . $this->getName() . '.';
    }
}

Отнаследуйте от него 2 класса: RussianHuman и EnglishHuman.

Реализуйте в них методы getGreetings(), которые будут возвращать приветствие на разных языках, вроде «Привет».

Реализуйте в них методы getMyNameIs(), которые будут возвращать на разных языках слова «Меня зовут».

В итоге метод introduceYourself должен возвращать строку, вроде «Привет! Меня зовут Иван.»

Создайте объекты этих классов и заставьте их поздороваться.

Комментарии
Этот урок набрал набрал достаточно большое количество комментариев и дальнейшее его комментирование отключено. Если вы хотели убедиться в правильности выполнения ДЗ или у вас возник вопрос по уроку, посмотрите ранее добавленные комментарии, кликнув по кнопке ниже. Скорее всего вы найдете там то, что искали. Если это не помогло - задайте вопрос в чате в телеграме - https://t.me/php_zone
Логические задачи с собеседований