ресурс для начинающих веб-разработчиков
комплексные веб-услуги по созданию сайтов

Справочный материал по основным языкам программирования и верстки сайтов.

Готовая методика создания простых и сложных динамичных сайтов, с использованием PHP и MySQL.

Использование веб-редактора Adobe Dreamweaver в разработке сайтов.

Использование графических редакторов Adobe Flash, Adobe Photoshop, Adobe Fireworks в подготовке веб-графики.

Разработка веб-сайтов под "ключ".

Разработка отдельных фрагментов сайтов, консультации по вопросам верстки веб-страниц и веб-программирования.

Объектно-ориентированное программирование и исключения. Создание классов. Cоздание объектов. Клонирование объектов

Создание классов

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

Механизм исключений введен в РНР для обработки особых ситуаций, называемых исключительными ситуациями или исключениями. Большие объемы кода современных приложений приводят к тому, что предусмотреть все возникающие ошибки или ситуации, приводящие к ним, невозможно, поскольку это требует дополнительного расширения кода, что в свою очередь способно привести к новым ошибкам. Поэтому практически во всех современных языках программирования вводится особый механизм обработки таких ошибочных ситуаций. Теперь для того, чтобы проверить определенные ошибки (например деление на нуль) в различных местах веб-приложения, больше не требуется анализировать корректность исполнения блока кода непосредственно в этом участке программы — такая проверка производится в специальной части программы, так называемом обработчике ошибок. Данный подход улучшает структуру и читаемость программы, т.к. части программы, отвечающие за выполнение прикладных задач, отделяются от частей, ответственных за обработку ошибок.

Создание классов

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

Объявление класса осуществляется при помощи ключевого слова class, за которым следует название класса и компоненты класса в фигурных скобках.

Компонентами класса являются переменные и функции, которые, как уже было сказано выше, называются членами и методами класса. Создадим пример самого простого класса.

Самый простой класс
<?php
//Начало класса
class PrimClass
{
//Объявляем член класса
var $member="Это член класса PrimClass <br>";
//Объявляем метод класса
function method()
{
echo "Вызван метод класса PrimClass <br>";
}
}
//Конец класса
//Объявляем объект класса PrimClass
$object=new PrimClass();
//вызываем метод method()
$object->method();
//Обращаемся к члену $member
echo $object->member;
?>

Объект класса объявляется с помощью ключевого слова new, за которым следует название класса. Как только объект класса объявлен, появляется возможность обращаться к его компонентам при помощи уточненного имени, которое включает имя объекта, следующую за ним стрелку (->) и имя метода или члена класса.

Примечание. При обращении к переменным класса знак $ перед ним не указывается.

Методы и члены класса могут вызываться не только из внешней программы, но из самого класса. Для того чтобы обратиться к переменной или методу класса, их вызов необходимо предварить конструкцией $this->. Переменная $this, которая не явно присутствует в каждом классе, является ссылкой на текущий объект класса и сообщает интерпретатору РНР, что происходит обращение к переменной данного класса, а не создание новой переменной.

Вызов метода класа другим методом
<?php
//Начало класса
class PrimClass
{
//Объявляем член класса
var $member="Это член класса PrimClass <br>";
//Объявляем метод класса
function method()
{
echo "Вызван метод класса PrimClass <br>";
}
function use_method()
{
echo "При помощи метода use_method() можно вызвать метод method() <br>";
$this->method();
}
}
//Объявляем объект класса PrimClass
$object=new PrimClass();
//вызываем метод use_method()
$object->use_method();
?>

Результат выполнения этого кода — две строки, одна из которых выведена методом use_method(), а вторая — методом method().

Членам класса можно присваивать значения как обычным переменным программы. Рассмотрим пример, где члену member класса PrimClass присваивается новое значение, а затем оно выводится при помощи метода PrintMember() этого класса.

Присваивание значения члену класса
<?php
//Начало класса
class PrimClass
{
//Объявляеь член класса
var $member="Это член класса PrimClass <br>";
//Объявляем метод класса
function PrintMember()
{
echo "Член member={$this->member}";
}
}
//Объявляем объект класса PrimClass
$obj=new PrimClass();
//Присваиваем члену класса member значение
$obj->member="Новому значению";
//обратимся к методу PrintMember() объекта $obj
$obj->PrintMember();
?>

Среди методов класса различают два особых метода: конструктор и деструктор.

Конструктор — специальный метод класса, предназначенный для инициализации членов класса. Этот метод выполняется раньше всех остальных методов класса во время объявления объекта. В конструкторе обычно осуществляют инициализацию членов класса и резервирование ресурсов, необходимых для работы объекта — выполняется открытие файлов, соединение с базой данных и т.д. Для того, чтобы использовать в классе конструктор, необходимо объявить в нем метод с именем _ _construct().

Примечание. Ключевое слово _ _construct() предваряется двумя знаками подчеркивания.

Деструктор — специальный метод класса, предназначенный для освобождения ресурсов, занятых объектом во время его существования. Этот метод всегда вызывается после всех остальных методов, во время уничтожения объекта. В нем обычно закрываются открытые файлы и соединения с базой данных.

Примечание. Конструктор и деструктор — это ключевые методы класса. Их наличие является одним из признаков объектно-ориентированной технологии. Это не значит, что в каждом классе должны обязательно присутствовать конструктор и деструктор — это не обязательные элементы класса и их следует применять только при необходимости.

Рассмотрим пример работы файла с конструктором и деструктором.

Использование конструктора и деструктора
<?php
class WrWiFl
{
//буфер
var $buff;
//имя файла
var $filename;
//конструктор класса
function __construct($filename)
{
//имя файла помещаем в член filename
$this->filename=$filename;
//проверяем существование файла
if(!file_exists($this->filename)) exit ("Файл не существует");
//открытие файла
$fd=fopen($filename, "r");
if(!$fd) exit ("Ошибка при открытии файла");
//чтение из файла
$this->buff=fread($fd, filesize($this->filename));
//закрытие файла
fclose($fd);
}
//метод выводит содержимое файла
function getContent()
{
return $this->buff;
}
//метод выводит размер файла
function getSize()
{
return filesize($this->filename);
}
//метод выводит число строк в файле
function getCount()
{
//если файл загружен
if(!empty($this->filename))
{
$arr=file($this->filename);
return count($arr);
}
else return 0;
}
}
?>

Методы класса, в том числе конструктор и деструктор, представляют собой обычные функции, которые могут принимать аргументы. Это придает классам дополнительную гибкость. К примеру, можно передавать названия файлов в качестве параметра конструктора. В этом случае можно работать с несколькими файлами, объявив несколько объектов.

Передача аргументов конструктору и деструктору
<?php
include "353.php";
echo "<pre>";
$first=new WrWiFl("count.txt");
$second=new WrWiFl("index.txt");
$star=new WrWiFl("file.txt");
echo "Размер (в байтах): {$first->getSize()}<br>";
echo "Число строк: {$first->getCount()}<br>";
echo "{$first->getContent()}<br>";
echo "Размер в байтах: {$second->getSize()}<br>";
echo "Число строк: {$second->getCount()}<br>";
echo "{$second->getContent()}<br>";
echo "{$star->getContent()}<br>";
echo "<?pre>";
?>

Конструктор так же применяется для помещения объектов других классов в качестве члена класса. Если класс содержит в качестве члена объект другого класса, то обращение к членам такого объекта также осуществляется при помощи стрелки: $obj->object->member.

Помещение объекта одного класса в другой класс
<?php
//внутренний класс Inner
class Inner
{
var $member="Член member класса Inner";
//Объявляем метод
function method()
{
echo "Метод method() класса Inner";
}
}

//Внешний класс Outer
class Outer
{
//Конструктор
function __construct()
{
$this->objt=new Inner;
}
}
//Объявляем объект класса Outer
$obj=new Outer;
//Обратимся к члену member объекта $object класса Inner
echo "{$obj->objt->member}<br>";
//Обратимся к методу method() объекта $object класса Inner
echo "{$obj->objt->method()}<br>";
?>

Число цепочек из стрелок -> не ограничено, т.е. можно создавать любое количество вложенных объектов.

Примечание. Для того, чтобы объявить член класса, так же как и в случае обычных переменных, необязательно обращаться к нему явно. При первом обращении к переменной при помощи конструкции "$this->переменная" создается новый член класса.

Cоздание объектов

Объекты объявляются при помощи ключевого слова new и являются экземплярами класса. Объекты являются переменными, тип и свойства которых определяются исходным классом. При работе с объектами можно создавать массив объектов.

Работа с массивом объектов
<?php
class work
{
var $name;
}
//Объявляем массив из 10 объектов класса work
$works=array();
for($i=0; $i<10; $i++)
{
$works[$i]=new work();
$works[$i]->name="Это объект номер $i";
}
for($i=0; $i<10; $i++)
{
echo $works[$i]->name;
echo "<br>";
}
?>

Объекты, как и обычные переменные, можно передавать в качестве аргумента функции.

Передача объектов через функцию
<?php
class Brend
{
var $name;
}
function ch_name($drin, $name)
{
$drin->name=$name;
}
$drink=new Brend;
$drink->name="Cок";
var_dump($drink->name);
ch_name($drink, "Кофе");
echo "<pre> Напиток: {$drink->name}\n";
?>

Объекты моут выступать не только как параметры функций, но и в качестве возвращаемых значений. Объект, возвращаемый функцией, можно присвоить другому объекту или вызвать его методы или члены непосредственно.

Непосредственный вызов методов класса
<?php
//Объект "круг"
class Circle
{
//метод, описывающий класс Circle
function describe()
{
echo "Круг <br>";
}
}
//Объект квадрат
class Square
{
//метод, описывающий класс Square
function draw()
{
echo "Квадрат <br>";
}
}
//Функция, возвращающая объект
function ShapeFactoryMethod($shape)
{
switch($shape)
{
case "Circle":
return new Circle();
case "Square":
return new Square();
}
}
//Можно непосредственно вызвать методы объекта
ShapeFactoryMethod("Circle")->describe();
ShapeFactoryMethod("Square")->draw();
?>

Присваивание одного объекта другому тоже происходит по ссылке, т.е. после того, как один объект присвоин другому, ссылки указывают на один и тот же объект.

<?php
class TestClass
{
//Объявляем член класса
var $member;
//Объявляем метод класса
public function method()
{
echo "Вызван метод класса";
}
}
//Объявляем два объекта класса TestClass
$first=new TestClass();
$second=new TestClass();
//Члену объекта $first присвоим значение
$first->member=3;
//Присвоим один объект другому
$second=$first;
echo $second->member. "<br>"; // 3
//Изменим значение члена member объекта $second
$second->member=5;
//Член member объекта $second тоже изменил значение
echo $first->member. "<br>"; // 5
?>

После того как объекту $second был присвоен объект $first, значение члена member стало равно 3, но изменение этого члена в объекте $second, так же изменяет его в объекте $first. Данную особенность объектов следует всегда учитывать, т.к. в противном случае это может стать причиной сложноотлаживаемых ошибок. В объектно-ориентированной модели РНР существует текже метод тосного копирования объектов, в результатекоторого получаются два независимых объекта одинакового содержания, но изменения, которым подвергается один объект, не отражаются на другом объекте. Механизм такого присваивания называется клонированием объектов.

Клонирование объектов

Часто от объектов требуется присваивание не по ссылке, а точное копирование всех переменных из одного объекта в другой, как это происходит в случае обычных переменных. Для этого в РНР5 было введено ключевое слово clone, возвращающее копию объекта.

Примечание. Ранние версии РНР использовали для клонирования объекта предопределенный метод __clone(), который в настоящее времяявляется зарезервированным, но не используется. Разработчики РНР пришли к выводу, что новый способ клонирования объектов при помощи ключевого слова clone более читабельный.

Клонирование объекта
<?php
class TestClass
{
//Объявляем член класса
var $member;
//Объявляем метод класса
public function method()
{
echo "Вызван метод класса";
}
}
//Объявляем два объекта класса TestClass
$first=new TestClass();
$second=new TestClass();
//Члену объекта $first присвоим значение
$first->member=3;
//Присвоим клон объекта другому объекту
$second=clone $first;
echo $second->member. "<br>"; // 3
//Изменим значение члена member объекта $second
$second->member=5;
//Член member объекта $first не изменил свое значение
echo $first->member. "<br>";
?>

В отличие от предыдущего примера, после присваивания клона объекта $first объекту $second оба объекта ведут себя независимо, как два различных объекта.