Наследование, в этом принципе — вся суть объектно-ориентированного программирования. Каждый дочерний элемент наследует методы (methods), свойства (properties), константы (constants) прописанные в родительском. Он может использовать их все, отбросить часть или добавить новые. При этом заново прописывать эти атрибуты и методы не нужно.
Разработчик создаёт:
- Класс с определёнными свойствами, методами, константами;
- Подкласс на его основе, который берёт свойства класса (или методы, константы) и добавляет свои;
- Объект подкласса, который также копирует его свойства (или методы, константы) и добавляет свои.
Также стоит обратить внимание на модификаторы доступа (property visibility, method visibility — область видимости для свойств и методов класса [public, protected]), чтобы они разрешали вам переопределить свойство или метод. В ином случае возникнет ошибка (например, «Cannot access private property», «Cannot access private method»).
Для того чтобы указать родительский класс (от которого будут браться данные/код) нужно добавить после объявления класса ключевое слово extends
(переводится как «расширяет»).
Цепочка наследования
В PHP наследовать можно только один класс. Точно так же как и в Java. Множественное наследование в этих языках было убрано специально, из-за его высокой сложности и проблем, которые оно добавляет (например, коллизии методов и свойств). С другой стороны, сама по себе цепочка наследования может быть сколь угодно глубокой:
class A {}
class B extends A {}
class C extends B {}
class D extends C {}
Конструкторы и наследование
При определении конструктора в дочернем классе вы берете на себя ответственность за передачу требуемых аргументов родительскому классу. Если же вы этого не сделаете, то у вас получится частично сконструированный объект. Чтобы вызвать нужный метод из родительского класса, вам понадобится обратиться к самому этому классу через дескриптор. Для этой цели в PHP предусмотрено ключевое слово parent
.
Чтобы обратиться к методу в контексте класса, а не объекта, следует использовать символы «::», а не «->». Поэтому конструкция parent::__construct()
означает следующее: «Вызвать метод __construct()
родительского класса».
Вызов переопределенного метода
Ключевое слово parent
можно использовать в любом методе, который переопределяет свой эквивалент в родительском классе. Когда мы переопределяем метод, то, возможно, хотим не удалить функции «родителя», а, скорее, расширить их. Достичь этого можно, вызвав метод родительского класса в контексте текущего объекта.
Пример
class Animal
{
public function __construct()
{
echo 'class Animal' . PHP_EOL;
}
// Обращаем внимание что все методы публичные
public function voice(): string
{
return 'sayed ';
}
public function type(): string
{
return 'animal';
}
}
// Наследуемся от класса Animal
class Dog extends Animal
{
// Переопределили конструктор
public function __construct()
{
echo 'class Dog';
}
// Переопределили метод
public function voice(): string
{
return 'gav';
}
}
// Наследуемся от класса Animal
class Cat extends Animal
{
// Переопределили конструктор
public function __construct()
{
parent::__construct(); // Но также вызовем конструктор класса Animal
echo 'class Cat';
}
// Переопределили метод
public function voice(): string
{
return parent::voice() . ' myaw'; // Вызвали метод voice() у родителя и добавили ' myaw'
}
}
$dog = new Dog(); // Выведет "class Dog"
echo PHP_EOL; // Перевод на новую строку
echo $dog->type(); // Выведет "animal"
echo PHP_EOL;
echo $dog->voice(); // Выведет "gav"
echo PHP_EOL;
echo PHP_EOL;
$cat = new Cat(); // Выведет "class Animal", а потом "class Cat"
echo PHP_EOL;
echo $cat->type(); // Выведет "animal"
echo PHP_EOL;
echo $cat->voice(); // Выведет "sayed myaw"
echo PHP_EOL;