ООП PHP
Интерфейсы и контроль типа
Оператор instanceof
Использование контроля типа совместно с интерфейсом
Интерфейсы очень удобно применять вместе с контролем типа.
Совместно с контролем типа интерфейсы предоставлют способ проверки того, что определенный объект может содержать некоторый набор методов.
Контроль типа
Оператор instanceof
Работая с объектами, мы можем контролировать, чтобы на вход в функцию подавался вполне конкретный объект.
Для примера в индексном файле (index.php) создадим три класса без реализации:
Создадим три класса без реализации:
- class A {}; - класс A
- class B extends A {}; - класс B, который будет наследовать класс A,
- class C {}; - класс C
Создадим три объекта от этих классов:
- $a = new A;
- $b = new B;
- $c = new C;
С помощью оператора instanceof (оператор проверки типов:php.net) сделаем проверку и получим после их распечатки (var_dump):
- var_dump($a instanceof A); - выведет boolean true
- var_dump($b instanceof B); - выведет boolean true
- var_dump($c instanceof A); - выведет boolean false
- читается, например, является ли объект $a экземпляром класса A, возвращает TRUE или FALSE.
Вместо ($b instanceof B) запишем ($b instanceof A) и распечатаем:
- var_dump($b instanceof A); - получим boolean true
- потому, что класс B расширяет класс A, он его наследует, и соответственно, наш объект $b является экземпляром двух классов: и класса B, и класса A
Использование контроля типа совместно с интерфейсом
В индексном файле создадим функцию, например, предложение какого-нибудь чехла (offerCase).
На вход будет подаваться некий продукт (объект) - $product и для него мы будем предлагать некий чехол:
function offerCase($product)
{
echo "<p>Предлагаем чехол для гаджета {$product->getName()} </p>" ;
}
- имя получаем через геттер getName() из класса Product
Создадим новый объект - ноутбук: $notebook = new NotebookProduct('Dell', 1000, 'Intel' ), у данного объекта есть свойство $name(имя)- оно приватное и получить мы его можем через геттер getName().
Вызовем функцию offerCase($notebook), где $notebook - в качестве параметра.
В результате работы этой функции в браузере будет выведено:
- Предлагаем чехол для гаджета Dell
Если мы вызовем функцию для объекта книжка - offerCase($book), то получим:
- Предлагаем чехол для гаджета Три мушкетера
файл index.php:
-- файл index.php --
<?php
(-1);
require_once 'classes/Product.php';
require_once 'classes/I3D.php';
require_once 'classes/NotebookProduct.php';
require_once 'classes/BookProduct.php';
function ($data)
{
echo '<pre>' . ($data, 1 ) . '</pre>';
}
// создадим функцию (предложение какого-нибудь чехла)
// на вход будет подаваться некий продукт $product - function offerCase($product)
function ($product)
{
echo "<p>Предлагаем чехол для гаджета {$product -> ()} </p>";
}
$book = new ('Три мушкетера', 20, 1000);
// создадим новый объект
$notebook = new ('Dell', 1000, 'Intel');
// вызовем функцию offerCase() с параметром $notebook
($notebook);
// предлагаем чехол для гаджета Три мушкетёра
($book);
($book);
echo $book -> ();
// Контроль типа
// для примера создадим 3 класса:
class {}; // класс A
class extends {}; // класс B, который будет наследовать класс A
class {}; // класс C
// создадим 3 объекта от этих классов
$a = new ;
$b = new ;
$c = new ;
// с помощью оператора instanceof (оператор проверки типов) сделаем проверку:
// читается: является ли объект $a экземпляром класса A, возвращает TRUE или FALSE
//var_dump($a instanceof A); // выведет true
//var_dump($b instanceof B); // выведет true
//var_dump($c instanceof A); // выведет false
($b );
($b );
// - выведет true, так как $b является объектом двух классов: A и B
// (так как класс B расширяет класс A (наследует))
// Объект является экземпляром всех классов, которые есть у него в родословной
?>
Выведет:
Предлагаем чехол для гаджета Dell (offerCase($notebook));
Предлагаем чехол для гаджета Три мушкетера (offerCase($book));
BookProduct Object
(
[numPages] => 1000
[name:Product:private] => Три мушкетера
[price:protected] => 20
[discount:Product:private] => 5
)
О товаре:
Наименование: Три мушкетера
Цена со скидкой: 19
Цена без скидки: 20
Кол-во страниц: 1000
Скидка: 5%
boolean true (var_dump($b instanceof B));
boolean true (var_dump($b instanceof A));
- такая ситуация может возникнуть и с ней надо как-то бороться. Здесь на помощь нам приходят интерфейсы и контроль типов.
Совместно с контролем типов и интерфейсов мы можем дать средство пользователю проверять, что определенный объект (в нашем случае - это ноутбук), должен содержать определенный набор методов. В нашем случае, например, выбрать чехлы, которые подойдут под данный продукт.
Создадим интерфейс IGadget:
-- файл IGadget --
<?php
// Совместно с контролем типов и интерфейсов мы можем дать средство пользователю проверять,
// что определенный объект, в нашем случае - ноутбук,
// должен содержать определенный набор методов (предлагаемые чехлы должны
// подходить под данный продукт)
// создадим интерфейс IGadget
interface
{
public function (); // публичный метод getCase() без реализации
}
?>
Наши ноутбуки должны реализовывать данный интерфейс (в NotebookProduct.php). Если интерфейс будет пустым, то ничего реализовывать мы не будем.
Файл NotebookProduct.php
-- файл NotebookProduct.php --
<?php
// реализуем интерфейс IGadget в классе NotebookProduct
class extends implements
{
public $cpu;
public function ($name, $price, $cpu)
{
parent :: ($name, $price);
$this -> cpu = $cpu;
}
// в нашем классе мы обязательно должны реализовать интерфейсный метод getCase()
public function ()
{
//...
}
public function ()
{
$out = parent :: ();
$out .= "Процессор: {$this -> cpu}<br>";
return $out;
}
public function ()
{
return $this -> cpu;
}
public function ($name, $price, $cpu = '')
{
// --------------------------
($name);
($price);
($cpu);
}
}
?>
Подключим интерфейс IGadget в индексном файле (index.php).
И делаем проверку:
- var_dump($notebook instanceof NotebookProduct); - получаем boolean
- var_dump($notebook instanceof IGadget); - получаем boolean true
- var_dump($book instanceof IGadget); - получаем boolean false
Создавая метод (функцию) offerCase(), мы можем воспользоваться контролем типов совместно с интерфейсами.
Воспользуемся контролем типов и укажем, что данной функции на вход должен обязательно передаваться параметром объект и объект вполне конкретного класса (IGadget):
- offerCase(IGadget $product)
файл index.php:
-- файл index.php --
<?php
(-1);
// ВНИМАНИЕ: нужно соблюдать порядок подключения !!!
require_once 'classes/Product.php';
require_once 'classes/I3D.php';
// подключаем интерфейс IGadget.php
require_once 'classes/IGadget.php';
require_once 'classes/NotebookProduct.php';
require_once 'classes/BookProduct.php';
function ($data)
{
echo '<pre>' . ($data, 1 ) . '</pre>';
}
// создавая метод offerCase мы можем воспользоваться контролем типов совместно с интерфейсами
function ($product)
{
echo "<p>Предлагаем чехол для гаджета {$product -> ()} </p>";
}
$book = new ('Три мушкетера', 20, 1000);
$notebook = new ('Dell', 1000, 'Intel');
// вызовем функцию offerCase() с параметром $notebook
($notebook);
// для проверки:
// попытка предложить чехол для гаджета Три мушкетёра
// при отработки function offerCase(IGadget $product) - вызовет ошибку
// offerCase($book);
// делаем проверку:
// в браузере получаем boolean true - это значит, что наш ноутбук ($notebook - объект)
// является экземпляром класса NotebookProduct
($notebook );
// и одновременно он является экземпляром интерфейса (класса) IGadget
($notebook );
// в то время, как $book не является экземпляром интерфейса IGadget; (boolean false)
($book );
// распечатаем объект
($book);
// получаем информацию о продукте с помощью метода getProduct()
echo $book -> ();
//echo $notebook->getProduct();
?>
Получим:
Предлагаем чехол для гаджета Dell (offerCase($notebook));
boolean true (var_dump($notebook instanceof NotebookProduct));
boolean true (var_dump($notebook instanceof IGadget));
boolean false (var_dump($book instanceof IGadget));
BookProduct Object
(
[numPages] => 1000
[name:Product:private] => Три мушкетера
[price:protected] => 20
[discount:Product:private] => 5
)
О товаре:
Наименование: Три мушкетера
Цена со скидкой: 19
Цена без скидки: 20
Кол-во страниц: 1000
Скидка: 5%
boolean true (var_dump($b instanceof B));
boolean true (var_dump($b instanceof A));
Содержание папки 11 ("Интерфейсы и контроль типа"):
Наверх Наверх