Статья

📘 Глава 19. Наследование, расширяемость и автозагрузка классов

Мы подошли к следующему фундаментальному элементу ООП и хорошей архитектуры проекта — наследованию, расширяемости и автоматической загрузке классов (autoloading).


🧠 Что такое наследование?

Наследование позволяет создавать новые классы на основе уже существующих, повторно используя их функциональность. Это один из трёх китов ООП (вместе с инкапсуляцией и полиморфизмом).


📦 Пример

class Animal {
    protected string $name;

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

    public function speak() {
        echo "$this->name makes a sound.";
    }
}

class Dog extends Animal {
    public function speak() {
        echo "$this->name barks.";
    }
}

$dog = new Dog("Buddy");
$dog->speak(); // Buddy barks.
  • Класс Dog наследует от Animal

  • Метод speak переопределён

  • Можно обращаться к защищённому свойству $name


👀 Зачем это нужно?

  1. Избегаешь дублирования кода

  2. Расширяешь поведение базового класса

  3. Используешь полиморфизм — один интерфейс, разное поведение


⚙️ Наследование в реальном проекте

У тебя может быть базовый контроллер:

class Controller {
    protected function render(string $view, array $data = []) {
        extract($data);
        include __DIR__ . "/../Views/layout.php";
    }
}

А все остальные:

require_once __DIR__ . '/Controller.php';

class MessageController extends Controller {
    // теперь можно использовать $this->render()
}

🧩 Полиморфизм

Разные классы могут реализовывать один и тот же метод по-своему:

$animals = [
    new Dog("Rex"),
    new Animal("Generic")
];

foreach ($animals as $animal) {
    $animal->speak(); // вызовет соответствующий метод каждого класса
}

📦 Абстракции и интерфейсы (вкратце)

Базовые классы можно делать абстрактными, если они задают шаблон, а не конкретное поведение:

abstract class Shape {
    abstract public function area(): float;
}

class Circle extends Shape {
    public function __construct(private float $radius) {}

    public function area(): float {
        return pi() * $this->radius ** 2;
    }
}

🛠 Автозагрузка классов (Autoloading)

Чтобы не писать require на каждый класс, в PHP предусмотрена автозагрузка — файл с нужным классом подключается автоматически при первом обращении.


🪄 Пример собственной автозагрузки

spl_autoload_register(function ($class) {
    $path = __DIR__ . '/../app/' . str_replace('\\', '/', $class) . '.php';
    if (file_exists($path)) {
        require_once $path;
    }
});

Если класс App\Models\Message — файл должен быть app/Models/Message.php.


🧩 Используем пространства имён

namespace App\Controllers;

class MessageController {
    // ...
}

Теперь класс доступен как App\Controllers\MessageController.

Вызов в index.php:

use App\Controllers\MessageController;

$controller = new MessageController(...);

🎯 PSR-4 и Composer autoload

В продакшене лучше использовать Composer для автозагрузки. Это позволяет:

  • соблюдать стандарт PSR-4

  • не писать свой spl_autoload_register

  • подключать сторонние библиотеки


📦 composer.json

{
  "autoload": {
    "psr-4": {
      "App\\": "app/"
    }
  }
}

Команда для генерации автозагрузчика:

composer dump-autoload

Подключение в index.php:

require_once __DIR__ . '/../vendor/autoload.php';

Теперь use App\Models\Message; работает автоматически.


✅ Что ты усвоил:

  • Наследование и его применение

  • Расширение и переопределение методов

  • Абстракции и полиморфизм

  • Простая и PSR-4 автозагрузка через Composer


⏭ В следующей главе:

  • Разберём пространства имён (namespaces) подробнее

  • Создадим собственный базовый контроллер и модель

  • Разделим проект на логические уровни с помощью ООП

PHP
Для ответа вы можете авторизоваться