This article has been localized into Russian by the community.
Наследование
Наследование - один из наиболее важных аспектов ООП. Он позволяет одному классу наследовать поля и методы другого класса. Поначалу может быть трудно понять, почему это так здорово, поэтому давайте рассмотрим пример.
Представьте, что вам нужно описать разные типы животных. Вы можете создать классы Cat (Кошка), Dog (Собака) и т.д., но, скорее всего, вы вскоре осознаете, что у этих классов много общего. С другой стороны, у каждого вида есть и свои особенности. Для таких случаев наследование подходит как нельзя лучше. Идея в том, чтобы создать базовый класс Animal (Животное), а затем - дочерние классы для каждого вида животных. Еще одно преимущество такого подхода заключается в том, что у всех животных будет некоторая базовая функциональность, на которую всегда можно положиться.
И снова, это все может показаться излишне теоретизированным, и поначалу не слишком полезным. Но когда вы будете разрабатывать более сложные сайты, вы, скорее всего, столкнетесь с ситуациями, когда наследование окажется очень полезным. Давайте рассмотрим пример:
class Animal
{
public $name;
public function Greet()
{
return "Hello, I'm some sort of animal and my name is " . $this->name;
}
}
Очень простой класс, наподобие тех, что мы создавали в предыдущем параграфе. Однако, "some sort of animal" ("какое-то животное") - это не очень информативное описание, так что давайте создадим класс-наследник для собаки:
class Dog extends Animal
{
}
Класс собаки объявлен как обычно, но после его имени мы использовали ключевое слово extend (расширить), чтобы показать PHP, что класс Dog наследуется от класса Animal. Сейчас класс Dog ничем не отличается от класса Animal. Следующий код позволяет убедиться в этом:
$dog = new Dog();
echo $dog->Greet();
Вы увидите, что name и функция Greet() присутствуют в классе, но все еще имеют довольно расплывчатые формулировки. Давайте исправим это, создав специальную версию функции Greet() для собаки:
class Dog extends Animal
{
public function Greet()
{
return "Hello, I'm a dog and my name is " . $this->name;
}
}
Обратите внимание, что мы объявили функцию Greet() еще раз, поскольку мы хотим, чтобы она делала что-то другое, но переменную $name объявлять заново не пришлось - она уже есть в классе Animal. Как вы можете видеть, хотя $name не объявлена в классе Dog, мы можем использовать ее в Greet(). Теперь, когда оба класса объявлены, пора протестировать их. Следующий код позволит нам это сделать:
$animal = new Animal();
echo $animal->Greet();
$animal = new Dog();
$animal->name = "Bob";
echo $animal->Greet();
Мы начали с создания экземпляра класса Animal, и вызвали для него функцию Greet(). В результате получим общее приветствие, которое мы написали изначально. После этого мы создаем новый экземпляр класса Dog и присваиваем его в ту же переменную $animal, задав нашей собаке конкретное имя, а затем заново вызываем функцию Greet(). На этот раз будет вызвана версия Greet() для класса Dog, и мы получим более конкретное приветствие, т.к. теперь $animal - это собака.
Наследование устроено рекурсивно - можно создать еще один класс, который будет наследоваться от Dog, и он тоже станет наследником Animal - например, Puppy (Щенок). Класс Puppy получит поля и методы и от Dog, и от Animal.