Объектно-ориентированный PHP: работа с наследованием. Наследование в PHP

При работе с классами в PHP часто приходится расширять функционал кода. Но если изменять оригинальный класс нет возможности, то его можно легко расширить создав "копию".

Классы, которые расширяют оригинальный называют "дочерними ", а родительский - "суперклассом ". У суперкласса может быть множество дочерних классов.

extends

Рассмотрим основные принципы наследования классов:

  • С помощью наследования мы можем создавать классы, которые будут содержать в себе все свойства и методы родительского класса, т.е. дочерние классы наследуют public и protected свойства и методы родительского класса.
  • Дочерний класс является расширением родительского класса, так как кроме унаследованных свойств и методов он может содержать собственные.
  • Наследование устанавливается использованием слова extends при создании класса.
  • Если у наследника нет своего конструктора (о нем писал ранее), то автоматически запустится конструктор родителя. Если в дочернем классе есть конструктор, то родительский конструктор не будет запускаться.
  • В дочерних классах могут переопределяться свойства и методы суперкласса. Определяя подкласс, мы гарантируем, что его экземпляр определяется характеристиками сначала дочернего, а затем родительского класса.

Давайте рассмотрим простой пример. Пусть у нас есть класс Ploshad , который считает площадь поверхности. Но теперь нам понадобилось рассчитывать ее объем. Оригинальный класс изменять нельзя. Создадим дочерний класс Obyem , который будет наследовать все свойства и методы Ploshad , и добавим функционал для расчета объема:

class Ploshad {
protected $width;
protected $height;
public function __construct($x, $y) {
$this->width = $x;
$this->height = $y; }
public function Square() { return $this->width * $this->height; }
}

class Obyem extends Ploshad {
protected $glybina;
public function Obyemss($g) {
$this->glybina = $g;
return $this->Square()* $this->glybina;
}
}

За счет записи class Obyem extends Ploshad мы объявили, что класс Obyem наследует свойства и методы класса Ploshad и может ими управлять. Внутри Obyem мы прописали новой свойство $glybina и метод public function Obyemss($g) . Давайте теперь рассчитаем объем и площадь:

$obj = new Obyem(2,12); //создаем объект от наследника
echo "Площадь: ".$obj->Square(); //старая функция родителяя
echo "Объем: ".$obj->Obyemss(2); //новая функция наследника

Как видно из комментариев $obj теперь может использовать как старые методы класса Ploshad, так и новые дочернего класса Obyem.

При рассчете площади интерпретатор PHP ищет конструктор в Obyem классе, если его не находи, то запускает конструктор в Ploshad. Он переопределяет значения переданных свойств(Obyem(2,12)). Затем запускается метод Square() и использует эти данные.

В случае с объемом, также запускается конструктор в Ploshad, а затем метод Obyemss($g), в которой передается высота. Внутри метода используем рассчет площади умноженный на высоту и получаем результат.

Наследование используют, когда функционал внутри одного класса становится слишком сложным для понимания и работы с ним, а также для создания исключений или разграничения типов данных. Например, у вас есть класс для выгрузки книжных товаров с множеством полей (автор, год издания, число страниц). Теперь, если вам понадобилось выводить товар с другим типом, например: DVD игры, то у него будут другие параметры (системные требования). Поэтому если класс стал напоминать два класса, лучше сделать наследование.

Интерпретатор PHP всегда сначала смотрит на дочерний класс:

  1. Есть ли конструктор. Если есть, то игнорирует конструктор родителя
  2. Есть ли свойства и методы. Если в дочернем и родительском они совпадают, то используются дочерние. Таким образом, можно полностью переписать функционал методов родительского класса.

extends parent::

parent:: - используется если в дочернем классе нужно изменить функционал родительского метода

Пример:
class PloshadProcent extends Ploshad {
function Square() {
$str = parent::Square();
$str = $str*0.1;
return $str;
}
}

Теперь при вызове, мы получим 10% от нашей площади:
$obj2 = new PloshadProcent(2,12);
echo "Площадь 10%: ".$obj2->Square(); //выдаст 2.4

Мы переопредилили метод суперкласса Square() внутри PloshadProcent

Второй и очень важный способ применения parent:: заключается в переопределении функционала конструктора внутри дочернего класса. Это можно использовать, если в суперклассе нет каких-то новых свойств, для работы:

Пусть есть класс book и в нем конструктор принимает всего 2 параметра: $title, $price.

class book {
public $title;
public $price;
function __construct($title, $price) {
$this->title = $title;
$this->price = $price;
}
}

Вдруг нам понадобилось вывести новый параметр $pages. Создадим экземпляр класса new_book и сделаем в нем свой конструктор, в котором уже будут нужные данные: $title, $price, $pages

Когда в дочернем классе определяется свой конструктор, PHP не вызывает конструктор родительского класса автоматически. Это необходимо сделать вручную в конструкторе подкласса.

Дочерний класс в своем конструкторе вызывает конструктор своего родительского класса, передавая нужные аргументы для инициализации, исполняет его, а затем выполняется код, который реализует дополнительную функциональность, в данном случае инициализирует свойство подкласса.

class new_book extends book {
public $pages;
function __construct($title, $price, $pages) {
parent::__construct($title, $price); // вызываем метод-конструктор родительского класса
$this->pages = $pages; // инициализируем свойство определенное в подклассе
}
}
$obj = new new_book("азбука", 35, 500);
echo "Книга: $obj->title | Цена: $obj->price | Страниц: $obj->pages";

Таким образом, мы можем расширять функционал суперклассов, не изменяя их самих. В следующем уроке вы узнаете

Это вторая часть нашего учебника по объектам в PHP. Первая часть находится тут: объекты в PHP .

Что такое наследование в PHP

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

Дочерний класс является расширением родительского класса, так как кроме унаследованных свойств и методов он содержит собственные.

Наследование устанавливается использованием слова extends при создании класса.

Простой пример:

name, возраст: $this->age, "; } } class Son extends Dad // Son по американски — сын, наследник класса Dad (отец) { public $user = "Nicer", $password = "secretNic"; public function printUserInfo() { echo "логин: $this->user, пароль: $this->password."; } } $obj = new Son(); $obj->printInfo(); $obj->printUserInfo();

Как видите, мы работаем только с экзампларом дочернего класса Son, но получаем через него доступ к методу printInfo() родительского класса Dad. В этом смысл наследования в PHP.

Слово extends дословно переводится с английского как расширять. Так что записть " class Son extends Dad " очень легко понятна, а именно: "класс Son расширяет {класс} Dad".

Пример наследования классов

Прошлый урок мы закончили на примере класса:

id = $id; $this->type = "книга"; $this->name = "Война и мир"; $this->description = "Толстая книга из нескольких томов"; $this->price = "543.26"; } function printGoods() { echo " ID товара: $this->id. Тип товара: $this->type. Название: \"$this->name\". Описание: $this->description. Цена: $this->price."; } } $Goods = new Goods(124); $Goods->printGoods();

В этом примере у нас всё работает. Класс хранит информацию о товаре и может печатать её на экран методом printGoods(). Но проект будет развиваться, и информацию о каком-то товаре понадобиться представить в виде HTML-таблицы, а о каком-то отправить на почту. Один класс не должен делать всё это, для этих целей создаются разные классы.

Наследование в PHP id = $id; $this->type = "книга"; $this->name = "Война и мир"; $this->description = "Толстая книга из нескольких томов"; $this->price = "543.26"; } } class GoodsInfo extends Goods { function printGoods() { echo "ID товара: $this->id. Тип товара: $this->type. Название: \"$this->name\". Описание: $this->description. Цена: $this->price."; } } $Goods = new GoodsInfo(124); $Goods->printGoods();

В этом примере второй класс GoodsInfo объявлен с использование ключевого слова extends , что обозначает что он является наследником класса, имя которого указано далее, в нашем случае это класс Goods.

Класс GoodsInfo называется дочерним, а класс Goods родительским. Такие названия указывают на наследственную связь этих классов.

В дочернем классе GoodsInfo мы имеем доступ ко всем свойствам и методам родительского класса.

Так как в классе GoodsInfo нет своего конструктора, то автоматически запущен конструктор родителя. Если в дочернем классе есть конструктор, то родительский конструктор не будет запускаться.

Ещё раз напишу: фактически, дочерний класс представляет из себя расширение родительского класса. Ключевое слово extends , которым указывается родственная связь, так и переводится с английского - расширение.

То есть мы можем создать класс, который является хранилищем информации, и создать несколько дочерних классов, которые обрабатывают эту информацию, каждый класс при этом специализируется на свой задаче.

Уточнение типов объектов

Теперь вот ещё о чём следует написать, о проверке типов объектов.

Разобъём наши классы на два отдельных класса:

Наследование в PHP id = $id; $this->type = "книга"; $this->name = "Война и мир"; $this->description = "Толстая книга из нескольких томов"; $this->price = "543.26"; } } class GoodsInfo // Этот класс уже не дочерний { function printGoods($Goods) // метод должен получать объект { echo "ID товара: $Goods->id. Тип товара: $Goods->type. Название: \"$Goods->name\". Описание: $Goods->description. Цена: $Goods->price."; } } $Goods = new Goods(124); $GoodsInfo = new GoodsInfo(); $GoodsInfo->printGoods($Goods); ?>

Пример работает точно так же, но на что тут нужно обратить внимание. Во-первых, область видимости свойств класса Goods стала public , иначе мы не получим к ним доступ из класса GoodsInfo, так как это уже не дочерний класс, а область видимости protected делает свойства доступными только дочерним классам.

Также обратите внимание, что область видимости была определена для метода printGoods() в классе GoodsInfo, это тоже можно делать.

Метод printGoods() на вход должен получать только объект класса Goods, и нам очень желательно проверить это. Проверим мы это так:

Public function printGoods(Goods $Goods) // метод должен получать объект { echo " ID товара: $Goods->id. Тип товара: $Goods->type. Название: \"$Goods->name\". Описание: $Goods->description. Цена: $Goods->price. "; }

Строка printGoods(Goods $Goods) , сначала идёт имя класса, которому должен соответствовать объект-аргумент, а потом уже аргумент. Если методу будет передан аргумент элементарного типа (string , integer , float , boolean) или объект другого типа, то будет сгенерирована ошибка.

Использование такого приёма очень правильно с точки зрения безопасности сценариев.

Таким образом можно проверять типы объектов и массивы, вот синтаксис для проверки массивов:

public function printGoods(array $Goods) {...}

А строки и другие элементарные типы нужно проверять специальными функциями.

Также можно требовать, чтобы аргумент был или определённого типа, либо нулевым значением (NULL).

public function printGoods(array $Goods=null) {...}

Область видимости в PHP

Теперь можно закрыть тему области видимости свойств и методов. Есть три ключевых слова, для определения разной области видимости.

  • public - доступно всем.
  • protected - доступно этому классу и дочерним, а также их объектам.
  • private - недоступно даже дочерним классам.

Это всё про области видимости.

Работа с наследованием в PHP

Из дочернего класса можно обратиться к методу родительского класса. Для этого используется дескриптор (по английски - родитель).

Наследование в PHP id = $id; $this->type = "книга"; $this->name = "Война и мир"; $this->description = "Толстая книга из нескольких томов"; $this->price = "543.26"; } } class GoodsInfo extends Goods { protected $discount = "скидка"; function __construct($id) { parent::__construct($id); $this->discount = 10; // скидка в процентах } function discountGoods() { echo "Размер скидки: ".($this->price * ($this->discount / 100)); } } $Goods = new GoodsInfo(124); $Goods->discountGoods();

Обратите внимание, что для доступа к родительскому классу мы использовали двойное двоеточие " :: ". Обращаясь к методу к контексте класса используем " :: ", а в контексте объекта используем " -> ".

Ключевое слово parent в PHP используется при переопределении методов в дочерних классах, подробнее вы можете прочитать по ссылке.

К методу класса можно обратиться напрямую, используя двойное двоеточие " :: ". Вот пример синтакиса:

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

Сначала пишем имя класса, потом двойное двоеточие, потом метод.

Резюме

Итак, мы изучили механизм наследования. Конечно, ещё много придётся изучать, данная информация лишь вводная.

Продолжим, следующий урок:

Наследование - это механизм объектно ориентированного программирования, который позволяет описать новый класс на основе уже существующего (родительского).

Класс, который получается в результате наследования от другого, называется подклассом. Эту связь обычно описывают с помощью терминов «родительский» и «дочерний». Дочерний класс происходит от родительского и наследует его характеристики: свойства и методы. Обычно в подклассе к функциональности родительского класса (который также называют суперклассом) добавляются новые функциональные возможности.

Чтобы создать подкласс, необходимо использовать в объявлении класса ключевое слово extends , и после него указать имя класса, от которого выполняется наследование:

age = $age; } function add_age () { $this->age++; } } // объявляем наследуемый класс class my_Cat extends Cat { // определяем собственный метод подкласса function sleep() { echo "
Zzzzz..."; } } $kitty = new my_Cat(10); // вызываем наследуемый метод $kitty->add_age(); // считываем значение наследуемого свойства echo $kitty->age; // вызываем собственный метод подкласса $kitty->sleep(); ?>

Подкласс наследует доступ ко всем методам и свойствам родительского класса, так как они имеют тип public . Это означает, что для экземпляров класса my_Cat мы можем вызывать метод add_age() и обращаться к свойству $age не смотря на то, что они определены в классе cat . Также в приведенном примере подкласс не имеет своего конструктора. Если в подклассе не объявлен свой конструктор, то при создании экземпляров подкласса будет автоматически вызываться конструктор суперкласса.

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

age"; } } class my_Cat extends Cat { public $age = 10; } $kitty = new my_Cat; $kitty->foo(); ?>

При вызове $kitty->foo() интерпретатор PHP не может найти такой метод в классе my_Cat , поэтому используется реализация этого метода заданная в классе Cat . Однако в подклассе определено собственное свойство $age , поэтому при обращении к нему в методе $kitty->foo() , интерпретатор PHP находит это свойство в классе my_Cat и использует его.

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

foo(new my_Cat); ?>

Мы можем обращаться с экземпляром класса my_Cat так, как будто это объект типа Cat , т.е. мы можем передать объект типа my_Cat методу foo() класса Cat , и все будет работать, как надо.

Оператор parent

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

Чтобы вызвать нужный метод из родительского класса, вам понадобится обратиться к самому этому классу через дескриптор. Для этой цели в PHP предусмотрено ключевое слово parent . Оператор parent позволяет подклассам обращаться к методам (и конструкторам) родительского класса и дополнять их существующую функциональность. Чтобы обратиться к методу в контексте класса, используются символы " :: " (два двоеточия). Синтаксис оператора parent:

Parent::метод_родительского_класа

Эта конструкция вызовет метод, определенный в суперклассе. Вслед за таким вызовом можно поместить свой программный код, который добавит новую функциональность:

title = $title; $this->price = $price; } } class new_book extends book { public $pages; function __construct($title, $price, $pages) { // вызываем метод-конструктор родительского класса parent::__construct($title, $price); // инициализируем свойство определенное в подклассе $this->pages = $pages; } } $obj = new new_book("азбука", 35, 500); echo "Книга: $obj->title
Цена: $obj->price
Страниц: $obj->pages"; ?>

Когда в дочернем классе определяется свой конструктор, PHP не вызывает конструктор родительского класса автоматически. Это необходимо сделать вручную в конструкторе подкласса. Подкласс сначала в своем конструкторе вызывает конструктор своего родительского класса, передавая нужные аргументы для инициализации, исполняет его, а затем выполняется код, который реализует дополнительную функциональность, в данном случае инициализирует свойство подкласса.

Ключевое слово parent можно использовать не только в конструкторах, но и в любом другом методе, функциональность которого вы хотите расширить, достигнуть этого можно, вызвав метод родительского класса:

name}."; return $str; } } class my_Cat extends Cat { public $age = 5; function getstr() { $str = parent::getstr(); $str .= "
Возраст: {$this->age} лет."; return $str; } } $obj = new my_Cat; echo $obj->getstr(); ?>

Здесь сначала вызывается метод getstr() из суперкласса, значение которого присваивается переменной, а после этого выполняется остальной код определенный в методе подкласса.

Теперь, когда мы познакомились с основами наследования, можно, наконец, рассмотреть вопрос видимости свойств и методов.

public, protected и private: управление доступом

До этого момента мы явно объявляли все свойства как public (общедоступные). И такой тип доступа задан по умолчанию для всех методов.

Элементы класса можно объявлять как public (общедоступные), protected (защищенные) и private (закрытые). Рассмотрим разницу между ними:

  • К public (общедоступным) свойствам и методам, можно получить доступ из любого контекста.
  • К protected (защищенным) свойствам и методам можно получить доступ либо из содержащего их класса, либо из его подкласса. Никакому внешнему коду доступ к ним не предоставляется.
  • Вы можете сделать данные класса недоступными для вызывающей программы с помощью ключевого слова private (закрытые). К таким свойствам и методам можно получить доступ только из того класса, в котором они объявлены. Даже подклассы данного класса не имеют доступа к таким данным.

public - открытый доступ:

hello"; } } $obj = new human; // доступ из вызывающей программы echo "$obj->age"; // Допустимо $obj->say(); // Допустимо?>

private - доступ только из методов класса:

age"; } } $obj = new human; // напрямую из вызывающей программы доступа к закрытым данным нет echo "$obj->age"; // Ошибка! доступ закрыт! // однако с помощью метода можно выводить закрытые данные $obj->say(); // Допустимо?>

protected - защищенный доступ:

Модификатор protected с точки зрения вызывающей программы выглядит точно так же, как и private: он запрещает доступ к данным объекта извне. Однако в отличие от private он позволяет обращаться к данным не только из методов своего класса, но также и из методов подкласса.

В PHP ООП наследование является фундаментальным принципом. Наследование влияет на то, как объекты соотносятся друг с другом. С его помощью мы можем создавать объекты, которые чем-то похожи, а в некоторых аспектах отличаются друг от друга.

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

При наследовании один класс используется в качестве базового класса или суперкласса. Мы также можем расширить вспомогательный, дочерний или производный от этого суперкласса класс. Подкласс наследует все открытые и защищенные функции-члены (методы ) суперкласса. Если вы не переопределите наследуемые методы, они сохранят свой первоначальный функционал. Но мы можем переопределить их и задать их функционал в соответствии с конкретными требованиями.

Допустим, у нас есть класс с именем person . Он имеет несколько атрибутов или свойств. Теперь, если мы наследуем класс worker от базового класса person, мы можем сказать, что worker является person . worker будет иметь все свойства person, а также дополнительные свойства. person — это суперкласс, а worker — это подкласс. person и worker будут иметь общие характеристики и методы.

При определении класса worker мы наследуем его от класса person. В результате нам не нужно снова определять свойства и методы класса, все наследуется по умолчанию. Это экономит время, нам не приходится снова писать один и тот же код.

Вот ООП PHP пример:

class Person { public $name; public $age; public function getName() { return $this->name; } } class worker extends Person { public $worker_id; public $record_date; public getWorkerId() { return $this->worker_id; } public getWorkerName() { return $this->getName();// getName() уже содержится в Person } }

В этом коде класс Person является базовым классом, а класс Worker — подклассом. Класс Worker может использовать метод getName() . Он был доступен в классе Person . Но так как класс Worker унаследовал его, то он может использовать этот метод.

Наследование является одним из способов, с помощью которых все свойства суперкласса наследуются подклассом, но свойства подклассов не наследуются в суперкласс. Наследование более ярко демонстрирует ООП PHP в действии. Так как это помогает расширить класс свойствами, унаследованными от родительского класса.

Переопределение функции при наследовании

Переопределение означает, что функции имеют одинаковые имена, но разный функционал. При наследовании в PHP , если дочерний класс определяет функцию с тем же именем, что и в родительском классе, она имеет приоритет над этой функцией. Это означает, что если функция наследуется от родительского класса, она может быть изменена в соответствии с конкретными требованиями:

name; } } class Animals extends LivingThings { var $name="Animals"; } class Horse extends Animals { var $name="Horse"; } $myclass = new Horse() ; $Horse->disp(); // Этот код выведет Horse ?>

Наследование в PHP и модификаторы доступа

В основах ООП PHP модификаторы доступа используются для контроля доступа из-за пределов класса к свойствам и методам-членам. Видимость данных и методов является очень важным аспектом, и для ограничения доступа к членам класса используются три модификатора доступа. Когда свойство или метод объявляются как статические, они могут быть вне конкретного класса.

Открытые члены

Этот тип присваивается свойствам или методам по умолчанию, даже если вы не используете идентификатор доступа public перед именем. Свойство или метод, объявленные как public , доступны в классе, в котором они были объявлены, из любого другого класса или из любого из его подклассов. Следовательно, никаких ограничений на доступ к ним нет.

Частные члены

Когда член объявлен, как privat , он доступен только в классе, в котором он был объявлен. Он не доступен из подклассов или из-за пределов класса.

Защищенные члены

В ООП PHP , когда свойство или метод объявляются защищенными, это означает, что они доступны в классе, в котором они были объявлены, а также из его подклассов. Но они не доступны вне пределов этого класса. Любое свойство или метод могут быть защищены с помощью ключевого слова protected , размещенного перед его именем.

Перевод статьи «PHP inheritance » был подготовлен дружной командой проекта .

Наследование - это один из "трёх китов " ООП , который позволяет создавать дочерние классы на основе родительских (супер-классов ), забрав у них свойства, методы и конструкторы. Хочется заметить, что наследование классов в PHP встречается только уже в серьёзных проектах. Вдобавок, новички наследование редко используют вообще, но тем не менее. Когда я делал свой движок для сайта (а он достаточно большой), то использовал наследование классов в PHP на полную катушку. И о том, как это делается, я и напишу в этой статье.

Давайте для начала создадим какой-нибудь несложный класс, например, класс, отвечающий за объект "Автомобиль " (в файле "car.php "):

class Car {
public $x;
public $y;
public function __construct($x, $y) {
$this->x = $x;
$this->y = $y;
}
public function move ($x, $y) {
$this->sound();
echo "Движение автомобиля из координат ($this->x, $this->y) в координаты ($x, $y)
";
$this->x = $x;
$this->y = $y;
}
public function sound() {
echo "Звук движения автомобиля
";
}
}
?>

В классе "Car " мы определили два свойства, отвечающие за текущие координаты местоположения автомобиля. Создали конструктор, который позволяет назначить начальные координаты. Затем создали метод move() , позволяющий начать движение в координаты, переданные в параметрах метода. Внутри этого метода мы вызываем метод sound() , который запускает звук движения. Вот такой придуманный класс.

Теперь создадим класс, отвечающий за "Легковой автомобиль " (в файле "auto.php "):

require_once "car.php";
class Auto extends Car {
public function move($x, $y) {
$this->sound();
echo "Движение легкового автомобиля из координат ($this->x, $this->y) в координаты ($x, $y)
";
$this->x = $x;
$this->y = $y;
}
public function sound() {
echo "Звук движения легкового автомобиля
";
}
}
?>

В самом начале мы подключаем наш класс "Car ". Затем мы начинаем создавать класс "Auto ", который является наследником для класса "Car " ("class Auto extends Car "). Ввиду того, что класс "Auto " уже забирает все свойства, методы и конструкторы, то нам нет необходимости их описывать заново. Однако, методы move() и sound() должны иметь другую реализацию, поэтому мы пишем другой код этих методов.

И, напоследок, создадим скрипт, который создаст объект "Car " и "Auto " и воспользуемся их методами и свойствами:

require_once "auto.php";
$car = new Car(10, 20);
echo $car->x;
echo "
";
echo $car->y;
echo "
";
$car->move(15, 5);
$auto = new Auto(5, 10);
echo $auto->x;
echo "
";
echo $auto->y;
echo "
";
$auto->move(0, 0);
?>

Вначале всё просто: мы создаём объект "Car ", выводим его свойства, используем его метод move() . А вот затем мы создаём объект "Auto ". Ввиду того, что мы не определяли своего конструктора в этом классе, то он берётся из родительского. Затем выводим свойства, которые мы, кстати, также не определяли, и они тоже берутся из родительского класса. А потом используем метод move() . И, разумеется, берётся реализация не из класса "Car ", а из класса "Auto ", который отвечает у нас за легковой автомобиль.

Однако, данный пример является несовершенным, точнее, даже очень грязным, ввиду наличия дублирования (повторяющийся код). И логики в том, что у нас существует "Автомобиль " и "Легковой автомобиль " тоже нет. Вы можете представить себе "Автомобиль "? Уверен, что у каждого из Вас будут совершенно разные образы. А вот "Легковой автомобиль " - это уже более точное определение (хотя тоже далеко от окончательно точного). И в ООП для неточных, абстрактных понятий, существует возможность создавать абстрактные классы , о которых мы поговорим в следующей статье. И Вы увидите, что код данного примера станет на порядок чище.

Кстати, даю домашнее задание: создать класс, отвечающий за "Грузовой автомобиль " (по аналогии с "Легковым автомобилем "), и который будет наследоваться от класса "Автомобиль ".

А наследование классов в PHP на этом не заканчивается, и уже в следующей статье мы продолжим эту тему.