ООП   PHP   web   4GL - визуальные среды

Лабораторная работа ч.3 по объектно-ориентированному программированию на PHP

Это третья часть лабораторной работы по ООП. Первый две части можно найти тут: часть 1 и часть 2.

Сегодня мы продолжаем заниматься практической деятельностью по освоению объектно-ориентированного программирования. И давайте начнем наш сегодняшний урок с такого понятия, как полиморфизм или по-другому — наследование.

Итак, что же такое полиморфизм?

Это способность класса наследовать все свойства и все методы предыдущего класса. В этом случае предыдущий класс будет выступать в роли родителя, а класс, который от него (родителя) наследует будет выступать в роли наследника.

Например, у меня есть класс Car со свойством, которое называется «год выпуска» ($year) и методом, который выводит скорость автомобиля и называется он — function paintSpeed():

<?php
class Car{
//свойства
public $year = 2003;
//метод
function paintSpeed(){
	echo "Скорость автомобиля = ".$this->speed;
    }
}
?>

На основе этого класса, я могу создать класс, например, класс Opel, который будет иметь такое же свойство и такой же метод, как мой класс Car. Теперь класс Car является родителем для класса Opel.

Так как же создается наследование?

Класс наследник или наследование (полиморфизм) создается с помощью ключевого слова extends.

Давайте посмотрим на примере:

<?php
//это класс родитель
class Car{
	//свойства
	public $year = 2003;
	
	//метод
	function paintSpeed(){
//указываем методу, чью скорость мы хотим получить. Идет обращение из метода к свойству
		echo "Скорость автомобиля = ".$this->speed;
	}
}

//это класс наследник, который имеет свойство $year и метод paintSpeed()
class Opel extends Car{
	//свойство
	public $model;
}
?>

Еще раз:

Когда мы создаем класс наследник, используя ключевое слово extends, то он автоматически наследует все свойства и методы класса родителя. В самом классе-наследнике мы не увидим этих свойств и методов, однако они там есть и к ним можно будет обращаться. Как именно это делать, я покажу далее.

Однако и сам класс наследник наряду со свойствами и методами класса родителя может иметь так же и свои свойства и методы.

Важно отметить, что после ключевого слова extends обязательно должно идти название класса, от которого мы собственно все и наследуем.

Теперь давайте посмотрим, как мы можем обращаться из класса наследника к его собственным свойствам и методам, так и к унаследованным:

<?php
//это класс родитель
class Car{
	//свойства
	public $year = 2003;
	
	//метод
	function paintSpeed(){
//указываем методу, чью скорость мы хотим получить. Идет обращение из метода к свойству
		echo "Скорость автомобиля = ".$this->speed;
	}
}

//это класс наследник, который имеет свойство $year и метод paintSpeed()
class Opel extends Car{
	//свойство
	public $model;
}

$myCar = new Opel();
//обращение к свойству класса родителя
$myCar->$year;
//обращение к собственному свойству 
$myCar->$model;
?>

Соответственно из класса Opel мы тоже можем создать класс наследник.

Теперь давайте вернемся к нашей лабораторной работе.

Задание у нас будет следующее:

  1. Описать класс SuperUsers унаследованный от класса Users;
  2. В классе SuperUsers описать свойство character и создать объект, экземпляр класса SuperUsers;
  3. Задать значение свойству character = «admin»;
  4. Вызвать метод getInfo() для созданного объекта;
  5. Отдельно от метода getInfo() вывести значение свойства character;

Вот что у нас должно было получиться:

<?php
class Users{
	public $name;
	public $login;
	public $password;
	
	//создание конструктора
	function __construct($name, $login, $password){
		$this->name = $name;
		$this->login = $login;
		$this->password = $password;
	}
	
	//создаем метод clone
	function __clone(){
		$this->name = "User";
		$this->login = "User";
		$this->password = "qwerty";
	}
	
	//создаем методод getInfo()
	function getInfo(){
		echo "<p>Name: ".$this->name."<br>";
		echo "Login: ".$this->login."<br>";
		echo "Password: ".$this->password."<br>";
	}
}

$user1 = new Users("Vasya", "vas", "123");
	//выводим метод getInfo()
	$user1->getInfo();

$user2 = new Users("Petya", "pet", "321");
	//выводим метод getInfo()
	$user2->getInfo();

$user3 = new Users("Vova", "vov", "456");
	//выводим метод getInfo()
	$user3->getInfo();
//объект $user4 копия объекта $user3 
$user4 = clone $user3;
	$user4->getInfo();
	
	
	
	
//Создаем класс наследник от класса Users
class SuperUsers extends Users{
	//создаем свойство character
	public $character;
}
//создаем объект экземпляр класса SuperUsers
$user = new SuperUsers("SuperAdmin", "root", "admin1234");
//задаем значение свойству character = admin
$user->character = "admin";
//вызываем метод getInfo() для созданного объекта
$user->getInfo();
//выводим значение свойства character
echo $user->character;
?>

Запустив этот код вы увидите, что у нас появился новый пользователь SuperAdmin, который обладает такими же свойствами и методами, что и пользователи класса Users + он имеет собственное свойство-характеристику (character) — админ.

Друзья, обратите внимание, что когда мы только что создали объект класса SuperUsers, он также унаследовал и конструктор своего родителя Users. Конструктор родителя, как мы знаем может принимать три параметра ($name, $login, $password). А в классе наследнике у нас появляется четвертый параметр character, который мы прописали отдельно.

Вот тут мы с вами подходим к такому понятию, как перегрузка методов.

Что же это такое? Например, у нас есть класс родитель и класс наследник. В классе родителе описан метод getPrint() и в классе наследнике мы тоже описываем метод getPrint(), хотя он уже там есть, так как унаследован от класса родителя. Но описываем мы его немного с другими параметрами, которые нам нужны именно в классе наследнике. Так вот, при вызове метода из экземпляра класса будет вызван именно метод из класса наследника, то есть переписанный.

Знаю, немного запутанно получилось, поэтому давайте посмотрим на примере:

<?php
class Car{
	//свойство
	public $model = "Mazda";
	
	//метод
	function getPrint(){
		echo $this->model;
	}
}

//создаем класс наследник
class Infinity extends Car{
	//свойство
	public $country = "Japan";
	
	//метод, который мы перегружаем, то есть переписываем его с нужными нам здесь параметрами
	function getPrint(){
		echo "Перегруженный метод getPrint()";
	}
}

//создаем экземпляр класса Infinity
$myCar = new Infinity();
//вызываем метод getPrint()
$myCar->getPrint();//ВАЖНО! Будет вызван перегруженный метод из класса наследника Infinity
?>

Запустив этот код у нас выведется надпись — «Перегруженный метод getPrint()», а не слово «Mazda». Попробуйте в классе наследнике убрать перегруженный метод и вы увидите, что будет происходить обращение к обычному методу getPrint(), унаследованному от родителя и в этом случае выведется надпись «Mazda». Другими словами перегруженный метод у наследника как бы перекрывает родительский.

В связи с этим давайте выполним задание лабораторной работы. А именно:

  1. описать конструктор класса SuperUsers, который будет задавать начальные значения свойств;
  2. в классе SuperUsers описать метод getInfo(), который будет выводить значения этих свойств;
  3. создать заново объект класса SuperUsers и вызвать метод getInfo();

И вот что у вас должно получиться:

<?php
class Users{
	public $name;
	public $login;
	public $password;
	
	//создание конструктора
	function __construct($name, $login, $password){
		$this->name = $name;
		$this->login = $login;
		$this->password = $password;
	}
	
	//создаем метод clone
	function __clone(){
		$this->name = "User";
		$this->login = "User";
		$this->password = "qwerty";
	}
	
	//создаем методод getInfo()
	function getInfo(){
		echo "<p>Name: ".$this->name."<br>";
		echo "Login: ".$this->login."<br>";
		echo "Password: ".$this->password."<br>";
	}
}

$user1 = new Users("Vasya", "vas", "123");
	//выводим метод getInfo()
	$user1->getInfo();

$user2 = new Users("Petya", "pet", "321");
	//выводим метод getInfo()
	$user2->getInfo();

$user3 = new Users("Vova", "vov", "456");
	//выводим метод getInfo()
	$user3->getInfo();
//объект $user4 копия объекта $user3 
$user4 = clone $user3;
	$user4->getInfo();
	
	
	
	
//Создаем класс наследник от класса Users
class SuperUsers extends Users{
	//создаем свойство character
	public $character;
	//описываем конструктор для SuperUsers
	function __construct($name, $login, $password, $character){
		$this->name = $name;
		$this->login = $login;
		$this->password = $password;
		$this->character = $character;
	}
	//перегружаем метод getInfo
	function getInfo(){
		echo "<p>Name: ".$this->name."<br>";
		echo "Login: ".$this->login."<br>";
		echo "Password: ".$this->password."<br>";
		echo "Character: ".$this->character."<br>";
	}
}
//создаем объект экземпляр класса SuperUsers
$user = new SuperUsers("SuperAdmin", "root", "admin1234", "admin");
//вызываем метод getInfo() для созданного объекта
$user->getInfo();
?>

Однако, если мы посмотрим на наш код, то мы можем сказать, что здесь что-то не так. Мы говорили о том, что вся прелесть наследования заключается в том, что мы все забираем у класса родителя, а тут нам пришлось все переписать практически заново. В итоге у нас произошло увеличение кода, что в идеале не есть хорошо. А если предположить, что у нас от класса SuperUsers будет наследоваться еще один класс SuperPuperUser, а от него еще какой нибудь, то количество строк кода будет возрастать до неимоверных пределов. Поэтому с этим надо что-то делать.

Допустим, мы в данном случае перегрузили родительский метод. Поэтому метод родителя нам уже не доступен. А что если я хочу иметь возможность обратиться и к родительскому методу и перегруженному?

Для этих целей у нас существует замечательная конструкция — parent.

Записывается она так — parent->двойное двоеточие->имя метода.

parent::имя метода

Эта конструкция позволяет обратиться к родительскому методу. Суть его работы заключается в том, что когда мы перегружаем родительский метод в классе наследнике, нам уже не надо еще раз описывать метод родителя. Мы просто в перегруженном методе обращаемся к методу родителя посредством конструкции parent, а если у нас есть дополнения к методу, то указываем их ниже этой конструкции:

<?php
//Создаем класс наследник от класса Users
class SuperUsers extends Users{
	//создаем свойство character
	public $character;
	//описываем конструктор для SuperUsers
	function __construct($name, $login, $password, $character){
		//ОБРАЩАЕМСЯ К МЕТОДУ (КОНСТРУКТОРУ) РОДИТЕЛЯ ПОСРЕДСТВОМ PARENT
		parent::__construct($name, $login, $password);
		//+ у нас дополнительное свойство character, которое указываем ниже parent и не забываем также указать его в параметрах перегруженного метода
		$this->character = $character;
	}
	//перегружаем метод getInfo
	function getInfo(){
		//то же самое - обращаемся к родительскому методу getInfo()
		parent::getInfo();
		//+ дополнительное свойство
		echo "Character: ".$this->character."<br>";
	}
}
//создаем объект экземпляр класса SuperUsers
$user = new SuperUsers("SuperAdmin", "root", "admin1234", "admin");
//вызываем метод getInfo() для созданного объекта
$user->getInfo();
?>

Вот и все. В результате у нас ничего не измениться, за исключением того, что мы немного сократили количество кода.

Евгений Владимирович Андреев

ООП   PHP   web   4GL - визуальные среды

(время поиска примерно 20 секунд)

Знаете ли Вы, что диаграмма последовательности, Sequence diagram - это методология объектно-ориентированного проектирования, предназначенная для моделирования взаимодействия во времени. Диаграмма последовательности позволяет отслеживать поведение взаимодействующих групп объектов.

НОВОСТИ ФОРУМАФорум Рыцари теории эфира
Рыцари теории эфира
 01.10.2019 - 05:20: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вячеслава Осиевского - Карим_Хайдаров.
30.09.2019 - 12:51: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Дэйвида Дюка - Карим_Хайдаров.
30.09.2019 - 11:53: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Владимира Васильевича Квачкова - Карим_Хайдаров.
29.09.2019 - 19:30: СОВЕСТЬ - Conscience -> РУССКИЙ МИР - Карим_Хайдаров.
29.09.2019 - 09:21: ЭКОНОМИКА И ФИНАНСЫ - Economy and Finances -> КОЛЛАПС МИРОВОЙ ФИНАНСОВОЙ СИСТЕМЫ - Карим_Хайдаров.
29.09.2019 - 07:41: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Михаила Делягина - Карим_Хайдаров.
26.09.2019 - 17:35: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Андрея Пешехонова - Карим_Хайдаров.
26.09.2019 - 16:35: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> Проблема государственного терроризма - Карим_Хайдаров.
26.09.2019 - 08:33: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от О.Н. Четвериковой - Карим_Хайдаров.
26.09.2019 - 06:29: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Ю.Ю. Болдырева - Карим_Хайдаров.
24.09.2019 - 03:34: ТЕОРЕТИЗИРОВАНИЕ И МАТЕМАТИЧЕСКОЕ МОДЕЛИРОВАНИЕ - Theorizing and Mathematical Design -> ФУТУРОЛОГИЯ - прогнозы на будущее - Карим_Хайдаров.
24.09.2019 - 03:32: НОВЫЕ ТЕХНОЛОГИИ - New Technologies -> "Зенит"ы с "Протон"ами будут падать - Карим_Хайдаров.
Bourabai Research Institution home page

Боровское исследовательское учреждение - Bourabai Research Bourabai Research Institution