Практическая работа 18 Тема 9/1. Объектно-ориентированные возможности PHP 4 МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ

advertisement
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Практическая работа 18
Тема 9/1. Объектно-ориентированные
возможности PHP 4
Цель — исследовать возможности PHP 4 по созданию классов и их применению
в скриптах.
Задание:
1.
2.
3.
4.
Исследовать
Исследовать
Исследовать
Исследовать
правила работы со свойствами и методами классов.
механизм наследования классов.
правила инициализации свойств объекта при его создании.
вызов методов из родительского класса.
Технология выполнения
18.1. Исследование правил работы со свойствами
и методами классов
Язык
программирования
PHP
4 обладает
основными
объектноориентированными возможностями. В первую очередь возможностью создания
классов,
то есть
возможностью
инкапсуляции
программных
деталей.
Программирование объектов, созданных на основе класса, реализуется через
свойства (переменные класса) и методы (функции класса).
Для исследования правил работы со свойствами и методами классов в PHP
выполнить следующие упражнения:
Упражнение 18.1. Создание класса
Напомним, что при создании класса перед его именем используется ключевое
слово class, свойства класса (их еще называют переменные класса) объявляются
при помощи оператора var, а методы описываются по правилам обычных PHPфункций (поэтому методы в PHP-классах часто называют функциями класса).
В файловой структуре учебного Web-ресурса создайте каталог class и в нем —
PHP-файл, например 1.php. В этом файле напишите код простейшего класса
(рис. 18.1).
Рис. 18.1. Код класса с именем Name
1
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Этим кодом создан класс Name, в котором объявлены свойства $one и $too
и создан метод print_name, который распечатает переданные переменные. Если
теперь запустить созданный скрипт, то никакого результата не будет, так как
созданный класс является, лишь неким шаблоном, который сам по себе
в программах не используется. В программах используются объекты, созданные
на основе данного шаблона — класса. Однако функции методов можно вызывать
извне при помощи оператора ::.
Упражнение 18.2. Использование функций класса
Допишите непосредственный вызов функции
(рис. 18.2) и проверьте исполнение скрипта.
метода
созданного
класса
Рис. 18.2. Код класса Name с прямым вызовом функции метода
Упражнение 18.3. Создание объекта класса
При создании объекта класса этот объект получает имя с символом $ вначале,
как и любая переменная или массив в PHP-программе. После создания объекта
к его свойствам и методам можно обращаться с использованием оператора ->.
В созданный скрипт допишите код формирования нового объекта и обращения
к его свойствам и методу (рис. 18.3).
Рис. 18.3. Код создания объекта класса Name
и обращения к его элементам
В данном примере строку $obj = new Name; называют также инициализацией
класса. Говоря языком PHP, переменная $obj имеет тип Name и поэтому обладает
всеми свойствами и методами этого класса.
$obj->one — вызов свойства $one (в котором символ $ не используется!).
C помощью оператора присвоения = можно определить значение этого свойства.
2
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
$obj->too — аналогичный вызов свойства $too.
$obj->print_name — вызов единственного метода объекта $obj с указание
в качестве входных параметров обоих свойств этого объекта, определенных
выше.
Упражнение 18.4 . Доступ к свойствам внутри класса.
Как правило, методы класса работают со свойствами этого же класса. Для
упрощения и унификации кода часто используют служебное слово $this. Измените
метод print_name, используя $this, и проверьте его действие (рис. 18.4).
Рис. 18.4. Код примера метода
с использованием служебного слова $ this
Конструкция $this-> — это вызов всех элементов внутри самого класса. То есть
в этот раз мы не стали передавать значения свойств объекта $obj->one и $obj>too, а просто сразу распечатали их посредством $this->one $this->too.
Поскольку в любом классе может существовать несколько экземпляров
объектов, уточнение $this необходимо для ссылок на элементы (свойства
и методы), принадлежащие текущему объекту.
Упражнение 18.5 . Доступ к свойствам через методы класса
Прямое обращение к свойствам объекта извне класса противоречит принципу
инкапсуляции, и при создании объектно-ориентированных программ так
поступать не следует. Для управления свойствами объектов внутри их класса
обычно предусматриваются два метода — один для задания значения каждому
свойству, другой — для вывода значения этого свойства. На рис. 18.5. приведен
пример класса с одним свойством bgcolor и двумя методами для управления этим
свойством. Дописать этот скрипт в тот же файл перед скриптом упражнений 1 —
4.
3
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Рис. 18.5. Код примера класса Webpage
с управлением свойством через методы
Приведенный пример иллюстрирует принцип управления свойствами объекта.
Конструкцией типа $page ->setBgColor(«red»); (находящейся, например,
в отдельном файле или скрипте) можно определять все параметры объекта,
которые затем используются в своих местах программы.
Добавить в класс Webpage свойство text, которое будет определять цвет текста
Web-страницы. Создать два метода для управления значением этого свойства
и проверить в работе. Результат продемонстрировать преподавателю.
Реализовать управление свойствами объектов класса Name через метод.
Вариант метода представлен на рис. 18.6.
Рис. 18.6. Пример метода управления свойствами
объектов класса Name
Новый метод класса Name — функция change_name, в которую будем
передавать аргумент $name. Метод реализует деление аргумента на части при
помощи функции explode() и получение массива значений для свойств класса.
Таким образом, при обращении к методу change_name можно задать значения
сразу обоим свойствам объекта:
$obj->change_name("Степан Ефимыч");
4
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Вызовом метода print_name можно проверить результат:
$obj->print_name();
Такой вариант инициализации
значения всех свойств объекта.
свойств позволяет
одной строкой
задать
18.2. Исследование механизма наследования классов
Создадим новый класс Super_name,
существующего класса Name (рис. 18.7).
который
является
производным
от
Рис. 18.7. Пример кода производного класса
Для создания производного (дочернего) класса используется ключевое слово
extends. Если создать объект производного класса, то он будет обладать
свойствами и методами как своими, так и родительскими:
//объявляем объект класса Super_name
$supobj = new Super_name();
// вызываем функцию из его родительского класса change_name
$supobj->change_name("Степан Ефимыч");
// вызываем функцию самого класса Super_name
$supobj->add_name("Иванов");
// распечатываем результат
$supobj->print_name();
// Получим: Степан Ефимыч Иванов
Ответить на вопрос «Влияет ли изменение свойства too в производном объекте
на значение этого свойства в родительском объекте?». Проверить ответ, создав
различные объекты.
Создать производный класс Site на основе родительского класса Webpage, в
котором реализовать, например, управление шрифтом.
18.3. Исследование правил инициализации свойств
объекта при его создании
В объектно-ориентированном программировании инициализация свойств
объекта при его создании реализуется при помощи специальных методов,
5
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
называемых конструкторами. В PHP 4 нет конструктора, но имитировать его
работу можно при помощи метода, одноименного с классом. Такой метод
автоматически вызывается при создании нового объекта. Добавить в класс Name
одноименный метод, инициализирующий свойства объекта данного класса (рис.
18.8).
Рис. 18.8. Пример метода, инициализирующего свойства
объекта класса Name
Теперь при создании объекта класса Name в круглых скобках можно указать
значения для его свойств, например:
$obj = new Name("Петр Васильевич");
$obj->print_name();
Здесь при объявлении объекта в него сразу передали аргумент "Петр
Васильевич", после этого метод Name разложил содержимое этого аргумента на
составляющие, разделенные пробелами, и присвоил свойствам класса. Во второй
строке при помощи метода print_name вывели результат.
Следует отметить, что добавленный метод инициализации свойств объекта
работает и при создании объектов производных классов.
Создайте объект производного класса Super_name с указанием значения для
его родительских свойств в качестве аргумента:
$supobj = new Super_name("Семен Семеныч");
Проверьте результат.
Если
в
производном
классе
необходимо
выполнять
отличающуюся
инициализацию свойств, то в нем следует описать собственный одноименный
метод, который будет вызываться вместо родительского метода. Для того, чтобы
использовать и родительский метод инициализации, надо применить специальную
конструкцию при помощи оператора:: (рис. 18.9).
6
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Рис. 18.9. Пример инициализации свойств объекта
производного класса Super_Name
То есть при объявлении
$supobj = new Super_name("Петр Васильевич", "Иванов");
передаются два аргумента в класс Super_name, сразу вызывается метод
Super_name, а в нем вызывается метод Name родительского класса
Name::Name($Name); в данном случае передаем туда "Петр Васильевич", где
свойствам $this->one = $Name[0]; $this->too = $Name[1]; будут присвоены
значения "Петр" и "Васильевич", после этого к значению свойства $this->too
добавляется переменную $path. Получаем, что свойство $this->too имеет
значение "Васильевич Иванов". Выводим результат $supobj->print_name();
При инициализации объекта можно создать объект другого класса. В
следующем примере в метод инициализации объектов класса Name добавлено
условие:
function Name($name){
if ($name == "Invalid name"){
$this = new Close();
return;
}
$name = explode (" ",$name);
$this->one = $name[0];
$this->too = $name[1];
}
7
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
В этом примере при инициализации свойств объекта проверяется входной
аргумент, и если он равен Invalid name, то создаваемый объект будет класса
Close. Естественно, что такой класс должен существовать, например:
class Close {
var $too;
function print_name(){
print "Неправильное имя, доступ закрыт: $this->too";
}
}
При создании объекта класса Super_name с аргументом, в котором нет текста
Invalid name, например:
$obj = new Super_name("Степан Ефимыч", "Иванов");
При выводе результата
$obj->print_name();
получим: Степан Ефимыч Иванов
При создании объекта класса Super_name с аргументом, в котором есть текст
Invalid name, например:
$obj = new Super_name("Invalid name", "Иванов");
При выводе результата
$obj->print_name();
получим: Неправильное имя, доступ закрыт: Иванов
То есть, если имя неправильное, мы вызвали новый объект Close, а в старом
потерялись все параметры. Кроме этого, мы сказали return, то есть прекратили
функцию и, вызвав объект Close, получили новый объект $obj->print_name();
который и распечатал нашу программу, потому что в Close тоже есть функция
print_name().
18.4. Исследование вызова методов из родительского
класса
В приведенном выше примере (рис. 18.9) использовалось обращение к методу
базового класса с использованием его имени (Name::Name()). Это не совсем
удобно, потому что имя класса или иерархия классов может измениться, и тогда
8
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
придется переписывать код описаний всех классов с тем, чтобы привести
используемые в них имена в соответствие с новой иерархией.
Чтобы избежать подобной ситуации, вместо имени базового класса нужно
использовать ключевое слово parent (например, parent::Name()). Parent
ссылается на класс, прописанный после extends в объявлении производного
класса. Поэтому если вдруг иерархия классов изменится, то достаточно будет
внести изменения в имена, указанные после extends в описаниях классов.
Для того, чтобы проверить работу вызова через parent, скопируйте следующий
код в новый PHP-файл и проверьте результат его работы:
<?php
class Name {
var $name;
function Name($name){
$name = explode (" ",$name);
$this->name = "$name[0] $name[1]";
}
function print_name(){
$this->name .= " дописали Name";
print $this->name;
}
}
class Super_name extends Name {
function Super_name($name, $path){
parent::Name($name);
$this->name .= " $path";
}
function print_name(){
$this->name .= " дописали Super_name";
parent::print_name();
}
}
9
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
$obj
=
"Иванов");
new
Super_name("Степан
Ефимыч",
$obj->print_name();
?>
Получим:
Степан Ефимыч Иванов дописали Super_name дописали Name
Ключевое слово parent::print_name(); нужно, потому что как в одном, так и во
втором классе, есть одинаковые функции print_name(), и если такое слово не
поставить, то будет вызов функции print_name() из дочернего класса.
Задание на самостоятельную работу
1. Закрепить навыки работы в объектами в PHP 4. Для этого исследовать
структуру некоторый классов.
Следующий класс позволяет распечатать свойства и методы класса.
<?php
class Name {
var $one;
var $too;
function Name($Name){
$Name = explode (" ",$Name);
$this->one = $Name[0];
$this->too = $Name[1];
}
function print_name(){
print "$this->one $this->too";
}
}
class Super_name extends Name {
function Super_name($Name, $path){
Name::Name($Name);
$this->too .= " $path";
10
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
}
}
// функция по определению переменных класса
function print_var ($obj){
$arr = get_object_vars($obj);
foreach($arr as $key=>$val){ print " - переменные: \$$key = $val \n<br>";}
}
// функция по определению функций класса
function print_method ($obj){
$arr = get_class_methods(get_class($obj));
foreach($arr as $val){ print " - функции: function $val() \n<br>";}
}
// инициализируем оба класса
$Name = new Name("Николай Петрович");
$Super_name = new Super_name("Степан Ефимыч", "Иванов");
// распечатаем информацию о классах
print "Распечатать свойства: <b>".get_class($Name)."() </b>\n<br>";
print_var ($Name);
print_method($Name);
print "Распечатать свойства: <b>".get_class($Super_name)."() </b>\n<br>";
print_var ($Super_name);
print_method($Super_name);
?>
Получим такую распечатку:
Распечатать свойства: name()
- переменные: $one = Николай
- переменные: $too = Петрович
- функции: function name()
- функции: function print_name()
Распечатать свойства: super_name()
11
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
- переменные: $one = Степан
- переменные: $too = Ефимыч Иванов
- функции: function name()
- функции: function print_name()
- функции: function super_name()
По указанию преподавателя познакомиться с работой других классов. В
Интернете имеются целые библиотеки скриптов с классами для различных целей.
2. На основе материала лекции применить функции get_class_methods(),
get_class_vars() и get_object_vars() для вывода свойств и методов
класса Name. Следует помнить, что эти функции формируют массивы,
которые требуется выводить по элементам.
3. Из материала лекции проверить работу примера, в котором классы
используются для построения шаблона Web-страниц.
12
Download