# Определение принадлежности объекта к классу

Сейчас мы с вами изучим оператор `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`.

←→
↑