ООП PHP
Наследование
Ключевое слово parent
Наследование: php.net
Наследование - это некий механизм, посредством которого один или несколько классов можно получить из некоторого базового класса.
Класс Product (базовый класс) - должен содержать общие свойста и общие методы (общую логику).
Поэтому удаляем из класса все частные свойства и методы.
- Оставляем свойства общие для всех товаров.
- Конструктр будет задавать свойства, общие для всех товаров.
- Получим через гетеры getName() и getPrice() общие свойства товаров.
- Метод getProduct() - будет возвращать инфрмацию о товаре, используя общие свойства.
Файл Product.php
-- файл Product.php --
<?php
class
{
// общие свойства товаров
public $name; // наименование товара
public $price ; // цена товара
// конструктр будет задавать свойства, общие для всех
public function ($name, $price)
{
$this -> name = $name;
$this -> price = $price;
}
// метод getProduct() - будет возвращать инфрмацию о товаре, используя общие свойства
public function ($type = 'notebook')
{
$out = "<hr><b>О товаре:<b><br>
Наименование: {$this->name}<br>
Цена: {$this->price}<br> ";
}
// общие гетеры:
public function ()
{
return $this -> name ;
}
public function ()
{
return $this -> price ;
}
}
?>
В индексом файле в экземпляры класса передаем по два параметра: название и цена. Получаем общую для всех типов товаров информацию с помощью метода getProduct().
Файл index.php
-- файл index.php --
<?php
(-1);
require_once 'classes/Product.php';
function ($data)
{
echo '<pre>' . ($data, 1 ) . '</pre>';
}
// В экземпляре класса Product (книжка) - передаем только два параметра
$book = new ('Три мушкетера', 20);
// экземпляр класса Product (ноутбук)
$notebook = new ('Dell', 1000);
// распечатаем данные объекты
($book);
echo '<br>';
($notebook);
// получаем информацию о продукте с помощью метода getProduct()
echo $book -> ();
echo $notebook -> ();
?>
Выведет:
Product Object
(
[name] => Три мушкетера
[price] => 20
)
Product Object
(
[name] => Dell
[price] => 1000
)
-----------------------------------------------------
О товаре:
Наименование: Три мушкетера
Цена: 20
Кол-во страниц: 1000
-----------------------------------------------------
О товаре:
Наименование: Dell
Цена: 1000
В результате у нас выводится информация, общая для всех типов товаров: названия товаров и их цена. Специфичная информация каждого конкретного товара не выводится.
Поскольку у нас два типа товаров (ноутбук и книги), то есть смысл создать два дочерних класса: NotebookProduct и BookProduct.
Создаем дочерний класс NotebookProduct и добавим в него специфичные свойства, в нашем случае - $cpu.
Для того, что-бы один класс мог наследовать другой класс, используется ключевое слово extends (extends - расширять), и название класса, который расширяем - Product.
В этом случае все методы и свойства родительского класса Product - наследуются и они нам доступны.
Чтобы получить специфичные свойства и методы - опишем их в дочернем классе NotebookProduct. Объявим свойство $cpu - специфическое свойство для Notebook. В классе Product не было этого свойства, а в классе NotebookProduct мы его добавили - тем самым расширили класс Product.
Также добавим метод getCpu().
При создании объекта нам необходимо заполнить свойства значением. Для этого напишем конструктор (__construct).
Когда мы определяем метод с тем же названием (__construct), что и в родительском классе, то мы его перезаписываем (переопределяем), то есть, теперь будет работать этот метод, а не метод в родительском классе. Если мы хотим получить ту же самую функциональность, мы должны объявить те же самые параметры из родительского класса плюс добавить наши параметры: $name,$price плюс $cpu.
Ключевое слово parent
Для того, чтобы не дублировать код, используем ключевое слово parent и оператор разрешения области видимости "::".
С помощью ключевого слова parent (parent - это слово указывает на родительский класс) и
оператора разрешения области видимости "::" мы обращаемся к родительскому классу и
вызваем нужный нам метод (__construct), который требует два параметра $name и $price:
parent::__construct($name, $price).
Затем дописываем нужную нам функциональность (добавляем наш параметр):
$this->cpu=$cpu .
Теперь наш конструктор (перезаписанный) вызывает сначала родительский конструктор, который отработает, и затем будет отработывать добавленный нами код.
Аналогично переопределяем родительский метод getProduct():
Вызываем родительскую функциональность:
parent::getProduct()
- и сохраняем ее в переменную $out,
и далее дописываем переменную $out нашей новой функциональностью (информацией о процессоре)
$out .= "Процессор: {$this->cpu}<br>"
- и возвращаем переменную $out.
Файл NotebookProduct.php
-- файл NotebookProduct.php --
<?php
// создаем дочерний класс NotebookProduct
// добавляем специфичные свойства
// для того, что-бы один класс мог наследовать другой класс,
// ипользуется ключевое слово (extends - расширять),
// и класс, который расширяем - Product
class extends
{
// специфическое свойство для Notebook (мы расширили класс Product)
public $cpu;
// когда мы определяем метод с тем же названием, что и в родительском классе,
// то мы его перезаписываем (переопределяем),
// то есть, теперь будет работать этод метод, а не метод в родительском классе
// мы должны объявить те же самые параметры из родительского класса
// плюс добавить наши параметры
public function ($name, $price, $cpu)
{
//$this->name=$name; // параметры из родительского класса
//$this->price=$price;
// с помощью ключевого слова (parent - это слово указывает на
// родительский класс) и оператора (:: - разрешение области видимости)
// мы обратились к родительскому классу и вызвали нужный
// нам метод (__construct), который требует два параметра $name и $price
parent :: ($name, $price);
// дописываем нужную нам функциональность (добавляем наш параметр)
$this -> cpu = $cpu ;
}
// аналогично переопределяем родительский метод getProduct()
public function ()
{
// строки из метода (getProduct() класса Product) переносим
// сюда и присваиваем переменной $out
$out = parent :: ();
// дописываем переменную $out нашей новой функциональностью
$out .= "Процессор: {$this -> cpu}<br>" ;
// возвращаем переменную $out
return $out;
}
// метод getCpu()
public function ()
{
return $this -> cpu;
}
}
?>
Тоже самое сделаем и для дочернего класса BookProduct:
Файл BookProduct.php
-- файл BookProduct.php --
<?php
class extends
{
public $numPages;
public function ($name, $price, $numPages)
{
parent :: ($name, $price);
$this -> numPages = $numPages;
}
public function ()
{
$out = parent :: ();
$out .= "Кол-во страниц:: {$this -> cpu}<br>" ;
return $out;
}
public function ()
{
return $this ->numPages ;
}
}
?>
В итоге мы получили два класса NotebookProduct и BookProduct, которые расширяют родительский класс Product.
В индексном файле подключаем наши классы и создаем объекты уже этих классов и передаем им параметры из соответствующих конструкторов.
Файл index.php
-- файл index.php --
<?php
(-1);
require_once 'classes/Product.php';
// подключаем класс NotebookProduct
require_once 'classes/NotebookProduct.php';
// подключаем класс BookProduct
require_once'classes/BookProduct.php';
function ($data)
{
echo '<pre>' . ($data, 1 ) . '</pre>';
}
// создаем объект класса BookProduct и передаем параметры из конструктора BookProduct
$book = new ('Три мушкетера', 20, 1000);
// создаем объект класса NotebookProduct и передаем параметры из конструктора NotebookProduct
$notebook = new ('Dell', 1000, 'Intel');
// распечатаем данные объекты
($book);
echo '<br>';
($notebook);
// получаем информацию о продукте с помощью метода getProduct()
echo $book -> ();
echo $notebook -> ();
?>
Получим:
BookProduct Object
(
[numPages] => 1000
[name] => Три мушкетера
[price] => 20
)
NotebookProduct Object
(
[cpu] => Intel
[name] => Dell
[price] => 1000
)
--------------------------------------------------------------------------------
О товаре:
Наименование: Три мушкетера
Цена: 20
Кол-во страниц: 1000
--------------------------------------------------------------------------------
О товаре:
Наименование: Dell
Цена: 1000
Процессор: Intel
- В результате получаем вместо двух объектов класса Product, конкретные объекты класса BookProduct и класса NotebookProduct.
Никаких пустых свойств: для книжки - cpu и для ноутбука - numPages здесь нет.
Проблема дублирования кода, проблема каких-то лишних свойств для того или иного объекта - решены. При этом, если у нас появятся новые типы товаров, нам достаточно описать соответствующие классы и при этом наследоваться от суперкласса (родительского класса), в котором уже описана какая-то общая логока. И вся эта логика будет наследоваться дочерними классами. В дочерних классах останется только дописать специфичную логику для данного класса.
Наследовать можно один класс только от одного другого класса. Но PHP поддерживает цепочку наследований: сейчас мы наследуем класс BookProduct от класса Product (расширяем класс Product), но также мы можем создать какой-нибудь класс, который будет наследоваться от класса BookProduct (расширять класс BookProduct). Этот класс получит все свойства и методы, которые содержатся в классе BookProduct и в классе Product, то есть, он будет наследовать сразу два класса. Эта цепочка наследований не ограничена.
Содержание папки 8 ("Наследование"):
Наверх Наверх