Наследование классов – механизм позволяющий создавать классы (говорят подклассы) на основе других классов (называемых базовыми или суперклассами). Подклассы, в таком случае, "наследуют" структуру базовых классов, то есть получают возможность использовать все, что определено в базовом классе.

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

Рассмотрим наследование на примере структуры HTML. Каждый тег в HTML по своему уникален. С другой стороны, все они имеют общие аттрибуты и некоторые другие характеристики. Попробуем отобразить это с помощью иерархии классов.

<?php

// Базовый класс для всех тегов. Умеет работать с аттрибутами.
class HTMLElement
{
    public $body;
    public $attributes = [];

    public function __construct($attributes = [])
    {
        $this->attributes = $attributes;
    }

    public function setAttribute(string $key, $value)
    {
        $this->attributes[$key] = $value;
    }

    public function getAttribute(string $key)
    {
        return $this->attributes[$key];
    }

    public function getTextContent(string $key)
    {
        return $this->body;
    }

    public function setTextContent($body)
    {
        $this->body = $body;
    }


    protected function stringifyAttributes()
    {
        // build: key="value" key2="value2"
    }
}

Конкретные элементы, представленные тегами в HTML, наследуются от этого класса:

<?php

// Anchor – это ссылка. Класс HTMLAnchorElement описывает тег "a".
// Наследование выполняется через ключевое слово extends
class HTMLAnchorElement extends HTMLElement
{
    public function __toString()
    {
        // Родительский метод
        $attrLine = $this->stringifyAttributes();
        // Родительский метод
        $body = $this->getTextContent();
        return "<a{$attrLine}>{$body}</a>"
    }
}

Наследование записывается так: A extends B. Эта запись означает, что класс A наследуется от класса B. В отличие от интерфейсов, наследование классов в PHP – одиночное. Другими словами, наследоваться можно только от одного класса. Точно так же как и в Java. Множественное наследование в этих языках было убрано специально, из-за его высокой сложности и проблем, которые оно добавляет (например коллизии методов и свойств). С другой стороны, сама по себе цепочка наследования может быть сколь угодно глубокой: A extends B extends C extends D.

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

<?php

// Конструктор родителя
$anchor = new HTMLAnchorElement('Hexlet', ['href' => 'https://ru.hexlet.io']);
echo "Anchor: {$anchor}"; // __toString вызывается автоматически
// Anchor: <a href="https://ru.hexlet.io">Hexlet</a>

Внутри класса HTMLAnchorElement нет определения конструктора, но благодаря наследованию, HTMLAnchorElement имеет доступ ко всем методам и свойствам суперкласса. Любой публичный метод суперкласса, доступен для вызова из любого объекта подкласса. Причем это происходит как внутри, так и снаружи объектов. Если посмотреть выше на метод __toString(), то внутри него видны обращения к методам, определенным в базовом классе.


Дополнительные материалы

  1. https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)

Для продолжения нужно перейти в курс и вступить в него.