📘 Глава 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
👀 Зачем это нужно?
-
Избегаешь дублирования кода
-
Расширяешь поведение базового класса
-
Используешь полиморфизм — один интерфейс, разное поведение
⚙️ Наследование в реальном проекте
У тебя может быть базовый контроллер:
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) подробнее
-
Создадим собственный базовый контроллер и модель
-
Разделим проект на логические уровни с помощью ООП