Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Наследование

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

extends

Класс-наследник объявляют словом extends:

<?php
 
class Animal
{
    public function __construct(protected string $name) {}
 
    public function describe(): string
    {
        return "{$this->name} — животное";
    }
}
 
class Dog extends Animal
{
    public function bark(): string
    {
        return "{$this->name}: Гав!";
    }
}
 
$dog = new Dog('Шарик');
 
echo $dog->describe(), "\n"; // Шарик — животное
echo $dog->bark();           // Шарик: Гав!

У Dog нет своего конструктора и метода describe() — они достались от Animal.

protected

Модификатор protected — промежуточный между public и private: свойство недоступно снаружи, но доступно в самом классе и в его наследниках. Если бы $name было private, метод bark() не смог бы его прочитать.

Переопределение методов

Наследник может объявить метод с тем же именем — тогда будет вызываться его версия. Вызвать родительскую версию позволяет parent:::

<?php
 
class Cat
{
    public function sound(): string
    {
        return 'Мяу';
    }
}
 
class Kitten extends Cat
{
    public function sound(): string
    {
        return parent::sound() . '-мяу';
    }
}
 
echo (new Kitten())->sound(); // Мяу-мяу

Полиморфизм

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

<?php
 
class Animal
{
    public function sound(): string
    {
        return '...';
    }
}
 
class Cat extends Animal
{
    public function sound(): string
    {
        return 'Мяу';
    }
}
 
class Dog extends Animal
{
    public function sound(): string
    {
        return 'Гав';
    }
}
 
foreach ([new Cat(), new Dog(), new Animal()] as $animal) {
    echo $animal->sound(), "\n";
}

Циклу не нужно знать, кошка перед ним или собака.

Проверка типа

Оператор instanceof проверяет, принадлежит ли объект классу. Объект наследника считается и объектом родителя:

<?php
 
class Animal {}
class Dog extends Animal {}
 
$dog = new Dog();
 
var_dump($dog instanceof Dog);    // bool(true)
var_dump($dog instanceof Animal); // bool(true)

Частая ошибка

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

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.