Классы и объекты в PHP: наследование классов в PHP. Часть 4

Классы и объекты в PHP: наследование классов в PHP. Часть 4

При работе с классами в 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. Часть 4 | При работе с классами в PHP часто приходится расширять функционал кода. Но если изменять оригинальный класс нет возможности, то его можно легко расшир | http://blogprogram.ru/wp-content/uploads/2017/06/692-131x131.jpg