Наследование в PHP
Наследование в PHP: extends, переопределение методов, parent::__construct(), final-классы и методы.
Наследование позволяет создать новый класс на основе существующего, добавив или изменив поведение. Дочерний класс получает все свойства и методы родительского и может их переопределить.
Extends
Дочерний класс объявляется с ключевым словом extends:
<?php
class Animal {
public function __construct(
protected string $name,
) {}
public function speak(): string {
return "{$this->name} издаёт звук";
}
public function getInfo(): string {
return "Животное: {$this->name}";
}
}
class Dog extends Animal {
public function speak(): string {
return "{$this->name} говорит: Гав!"; // переопределяем метод
}
public function fetch(): string {
return "{$this->name} принёс мяч"; // новый метод
}
}
$dog = new Dog("Шарик");
echo $dog->speak(); // Шарик говорит: Гав!
echo $dog->getInfo(); // Животное: Шарик
echo $dog->fetch(); // Шарик принёс мяч
Вывод:
Шарик говорит: Гав! Животное: Шарик Шарик принёс мяч
Вызов родительского конструктора
Если дочерний класс объявляет конструктор, нужно вручную вызвать конструктор родителя через parent::__construct():
<?php
class Animal {
public function __construct(protected string $name) {}
}
class Dog extends Animal {
public function __construct(string $name, private string $breed) {
parent::__construct($name); // сначала инициализируем родителя
}
public function info(): string {
return "{$this->name} ({$this->breed})";
}
}
$dog = new Dog("Шарик", "Лабрадор");
echo $dog->info(); // Вывод: Шарик (Лабрадор)
Вывод:
Шарик (Лабрадор)
Переопределение метода и parent::
При переопределении метода можно вызвать версию родителя через parent::метод() — это удобно, когда нужно расширить поведение, а не заменить его полностью:
<?php
class Animal {
protected string $name;
public function __construct(string $name) {
$this->name = $name;
}
public function describe(): string {
return "Имя: {$this->name}";
}
}
class Cat extends Animal {
public function __construct(string $name, private string $color) {
parent::__construct($name);
}
public function describe(): string {
return parent::describe() . ", цвет: {$this->color}"; // дополняем
}
}
$cat = new Cat("Мурка", "серая");
echo $cat->describe();
Вывод:
Имя: Мурка, цвет: серая
Запрет наследования: final
Ключевое слово final запрещает наследование класса или переопределение метода:
<?php
class Vehicle {
final public function identify(): string {
return "Это транспортное средство";
}
}
class Car extends Vehicle {
// public function identify(): string { ... } // Fatal error!
}
final class Singleton {
// этот класс нельзя расширить
}
Используйте
finalосознанно: когда нужно гарантировать, что поведение класса не изменится. Чрезмерное применение затрудняет тестирование.
Коротко
extends— дочерний класс наследует все свойства и методы родителя.- Переопределяйте методы, объявляя их заново в дочернем классе.
parent::__construct()— вызов конструктора родителя; обязателен, если у дочернего класса есть свой конструктор.parent::метод()— вызов родительской реализации метода из дочернего.final classнельзя расширить;final functionнельзя переопределить.
Проверьте себя
1. Как в дочернем классе вызвать конструктор родительского класса?
Asuper()
Bparent::__construct()
Cbase::__construct()
D__parent()
2. Что произойдёт, если попытаться унаследоваться от final-класса?
AНаследование произойдёт, но final-методы не перекроются
BPHP покажет предупреждение, но продолжит работу
CFatal error: Cannot extend final class
DДочерний класс станет тоже final
3. Может ли дочерний класс PHP расширять несколько родительских классов одновременно?
AДа: class A extends B, C {}
BНет: PHP поддерживает только одиночное наследование
CДа, но только абстрактных классов
DДа, через запятую до 3 классов