Сейчас мы с вами изучим оператор instanceof
.
Данный оператор используется для определения
того, является ли текущий объект экземпляром
указанного класса.
Давайте посмотрим на примере. Пусть у нас даны какие-то два класса:
<?php
// Первый класс:
class Class1
{
}
// Второй класс:
class Class2
{
}
?>
Создадим объект первого класса:
<?php
$obj = new Class1;
?>
Проверим принадлежность объекта из переменной
$obj
первому классу и второму:
<?php
// Выведет true, тк объект принадлежит классу Class1:
var_dump($obj instanceof Class1);
// Выведет false, тк объект НЕ принадлежит классу Class2:
var_dump($obj instanceof Class2);
?>
Сделайте класс Employee
с публичными
свойствами name
(имя) и salary
(зарплата).
Сделайте класс Student
с публичными
свойствами name
(имя) и scholarship
(стипендия).
Создайте по 3
объекта каждого класса
и в произвольном порядке запишите их в массив
$arr
.
Переберите циклом массив $arr
и выведите
на экран столбец имен всех работников.
Аналогичным образом выведите на экран столбец имен всех студентов.
Переберите циклом массив $arr
и с
его помощью найдите сумму зарплат работников
и сумму стипендий студентов. После цикла
выведите эти два числа на экран.
Оператор instanceof и наследование
Пусть теперь у нас есть родительский класс и дочерний:
<?php
// Родительский класс:
class ParentClass
{
}
// Дочерний класс:
class ChildClass extends ParentClass
{
}
?>
Создадим объект дочернего класса:
<?php
$obj = new ChildClass;
?>
Проверим теперь с помощью instanceof
,
принадлежит ли наш объект классу ParentClass
и классу ChildClass
:
<?php
var_dump($obj instanceof ChildClass); // выведет true
var_dump($obj instanceof ParentClass); // тоже выведет true
?>
Как вы видите из примера - оператор instanceof
не делает различия при проверки между родительскими
и дочерними классами.
Не путайтесь - если объект будет действительно
родительского класса то, конечно же, проверка
на принадлежность к дочернему классу вернет
false
:
<?php
$obj = new ParentClass; // объект родительского класса
var_dump($obj instanceof ParentClass); // выведет true
var_dump($obj instanceof ChildClass); // выведет false
?>
Сделайте класс User
с публичным свойствами
name
и surname
.
Сделайте класс Employee
, который будет
наследовать от класса User
и добавлять
свойство salary
.
Сделайте класс City
с публичными свойствами
name
и population
.
Создайте 3
объекта класса User
,
3
объекта класса Employee
,
3
объекта класса City
, и в
произвольном порядке запишите их в массив
$arr
.
Переберите циклом массив $arr
и выведите
на экран столбец свойств name
тех
объектов, которые принадлежат классу User
или потомку этого класса.
Переберите циклом массив $arr
и выведите
на экран столбец свойств name
тех
объектов, которые не принадлежат классу User
или потомку этого класса.
Переберите циклом массив $arr
и выведите
на экран столбец свойств name
тех
объектов, которые принадлежат именно классу
User
, то есть не классу City
и не классу Employee
.
Применение
Давайте рассмотрим применение оператора instanceof
на достаточно сложном примере. Пусть у нас
есть вот такой класс для работников:
<?php
class Employee
{
private $name;
private $salary;
public function __construct($name, $salary)
{
$this->name = $name;
$this->salary = $salary;
}
public function getName()
{
return $this->name;
}
public function getSalary()
{
return $this->salary;
}
}
?>
Пусть также есть такой класс для студентов:
<?php
class Student
{
private $name;
private $scholarship; // стипендия
public function __construct($name, $scholarship)
{
$this->name = $name;
$this->scholarship = $scholarship;
}
public function getName()
{
return $this->name;
}
public function getScholarship()
{
return $this->scholarship;
}
}
?>
Как вы видите, и работник, и студент имеют имя и какой-то доход: у работника это зарплата, а у студента - стипендия.
Пусть теперь мы хотим сделать класс UsersCollection
,
предназначенный для хранения работников и
студентов. Работников мы будем хранить в
свойстве employees
, а студентов -
в свойстве students
:
<?php
class UsersCollection
{
private $employees = []; // массив работников
private $students = []; // массив студентов
}
?>
Давайте теперь реализуем единый метод add
для добавления и работников, и студентов.
Этот метод параметром будет принимать объект
и, если это работник - добавлять его в массив
работников, а если студент - в массив студентов.
Пример того, как мы будем пользоваться методом
нашим методом после его реализации:
<?php
$usersCollection = new UsersCollection;
$usersCollection->add(new Employee('john', 200)); // попадет к работникам
$usersCollection->add(new Student('eric', 100)); // попадет к студентам
?>
Итак, давайте реализуем описанный метод add
.
Здесь нам и поможет изученный нами оператор
instanceof
:
<?php
class UsersCollection
{
private $employees = []; // массив работников
private $students = []; // массив студентов
// Добавление в массивы:
public function add($user)
{
// Если передан объект класса Employee:
if ($user instanceof Employee) {
$this->employees[] = $user; // добавляем к работникам
}
// Если передан объект класса Student:
if ($user instanceof Student) {
$this->students[] = $user; // добавляем к студентам
}
}
}
?>
Давайте также реализуем методы для нахождения суммарной зарплаты и суммарной стипендии:
<?php
class UsersCollection
{
private $employees = [];
private $students = [];
public function add($user)
{
if ($user instanceof Employee) {
$this->employees[] = $user;
}
if ($user instanceof Student) {
$this->students[] = $user;
}
}
// Получаем суммарную зарплату:
public function getTotalSalary()
{
$sum = 0;
foreach ($this->employees as $employee) {
$sum += $employee->getSalary();
}
return $sum;
}
// Получаем суммарную стипендию:
public function getTotalScholarship()
{
$sum = 0;
foreach ($this->students as $student) {
$sum += $student->getScholarship();
}
return $sum;
}
}
?>
Реализуем также метод, который будет находить общую сумму платежей и работникам, и студентам:
<?php
class UsersCollection
{
private $employees = [];
private $students = [];
public function add($user)
{
if ($user instanceof Employee) {
$this->employees[] = $user;
}
if ($user instanceof Student) {
$this->students[] = $user;
}
}
public function getTotalSalary()
{
$sum = 0;
foreach ($this->employees as $employee) {
$sum += $employee->getSalary();
}
return $sum;
}
public function getTotalScholarship()
{
$sum = 0;
foreach ($this->students as $student) {
$sum += $student->getScholarship();
}
return $sum;
}
// Получаем общую сумму платежей и работникам, и студентам:
public function getTotalPayment()
{
return $this->getTotalScholarship() + $this->getTotalSalary();
}
}
?>
Проверим работу нашего класса:
<?php
$usersCollection = new UsersCollection;
$usersCollection->add(new Student('kyle', 100));
$usersCollection->add(new Student('luis', 200));
$usersCollection->add(new Employee('john', 300));
$usersCollection->add(new Employee('eric', 400));
// Получим полную сумму стипендий:
echo $usersCollection->getTotalScholarship();
// Получим полную сумму зарплат:
echo $usersCollection->getTotalSalary();
// Получим полную сумму платежей:
echo $usersCollection->getTotalPayment();
?>
Скопируйте мой код классов Employee
и Student
и самостоятельно не подсматривая
в мой код реализуйте такой же класс UsersCollection
.