Современные языки программирования обычно поддерживают или даже требуют применения объектно-ориентированного подхода при разработке программного обеспечения. В процессе объектно-ориентированной разработки предпринимается попытка задействования классификаций, отношений и свойств объектов системы для упрощения разработки программ и повторного использования кода.
Создание классов, атрибутов и операций в РНР
До сих пор мы рассматривали классы достаточно абстрактно. При создании класса в РНР используется ключевое слово class
.
Структура класса
Минимальный вариант объявления класса имеет следующий вид:
class classname
{
}
Чтобы быть полезными, классы должны иметь атрибуты и операции. Атрибуты создаются путем объявления переменных внутри определения класса с помощью ключевого слова var
. Следующий код создает класс classname
с двумя атрибутами: $attribute1
и $attribute2
.
class classname
{
var $attribute1;
var $attribute2;
}
Операции создаются путем объявления функций внутри определения класса. Следующий код создает класс classname
с двумя операциями, которые не выполняют никаких действий. Операция operation 1()
не принимает никаких параметров, а операция operation2()
принимает два параметра.
class classname
{
function operation1 ()
{
}
function operation2 ($param1, $param2)
{
}
}
Конструкторы
Большинство классов будет иметь специальный тип операции, называемый конструктором. Конструктор вызывается при создании объекта и обычно выполняет такие полезные задачи по инициализации, как установка приемлемых начальных значений атрибутов или создание других объектов, требуемых для данного объекта.
Конструктор объявляется так же, как и другие операции, но он имеет специальное имя __construct ()
. Это нововведение РНР5. В предыдущих версиях РНР функции конструктора получала то же имя, что и класс. для обратной совместимости, если в классе не определена функция __construct ()
, выполняется поиск функции, имя которой совпадает с именем самого класса.
Хотя конструктор можно вызвать вручную, его основное значение заключается в том, что он автоматически вызывается в момент создания объекта. Следующий код объявляет класс с конструктором:
class classname
{
function __construct ($param)
{
echo "Констуктор вызван с параметром $param <br>";
}
}
В настоящее время РНР поддерживает перегрузку функций, т.е. можно определять более одной функции с одним и тем же именем и различным количеством или типами параметров.
Деструкторы
Деструктор представляет собой противоположность конструктору. Механизм деструкторов появился в РНР5. Они позволяют выполнять определенные действия непосредственно перед уничтожением класса. Деструктор вызывается автоматически, когда все ссылки на класс удаляются или выходят за пределы области видимости.
Подобно именованию конструкторов, деструктор класса должен иметь имя __destruct ()
. Деструкторы не могут принимать параметры.
Создание экземпляров класса
После объявления класса необходимо создать объект — конкретный отдельный элемент, являющийся членом класса, с которым будет выполняться работа. Этот процесс называют также созданием экземпляров класса. Объект создается с помощью ключевого слова new
. При этом нужно указать, экземпляром какого класса будет объект, и предоставить все параметры, которые требуются для конструктора.
Следующий код объявляет класс classname
с конструктором, а затем создает три объекта типа classname
:
class classname
{
function __construct ($param)
{
echo "Констуктор вызван с параметром $param <br>";
}
}
$a = new classname ('Первый');
$b = new classname ('Второй');
$c = new classname ('');
Использование атрибутов класса
Внутри класса имеется доступ к специальному указателю с именем $this
. Если атрибут текущего класса имеет имя $attribute
, ссылка на него при установке или при обращении к переменной из операции внутри класса выполняется в виде:
$this -> attribute
Следующий код — пример установки и обращения к атрибуту внутри класса:
class classname
{
var $attribute;
function operation ($param)
{
$this -> attribute = $param
echo $this -> attribute;
}
}
Возможность доступа к атрибуту извне класса определяется модификаторами доступа. Класс, код которого приведен выше, никак не ограничивает доступ к атрибуту, поэтому к нему можно обратиться так, как показано ниже:
class classname
{
var $attribute;
}
$a = new classname ();
$a -> attribute = 'value';
echo $a -> attribute;
Непосредственное обращение к атрибутам вне класса — не очень хорошая идея. Одно из преимуществ объектно-ориентированного подхода в том, что он поощряет инкапсуляцию. Достигнуть этого можно с помощью функций __get
и __set
. Если вместо прямого доступа к атрибутам класса создать функцию доступа, весь доступ будет осуществляться через один раздел программного кода. Первоначальный вариант функций доступа может иметь следующий вид:
class classname
{
var $attribute;
function __get ($name)
return $this -> $name;
}
function __set ($name, $value)
{
$this -> $name = $ value;
}
}
Этот код предоставляет минимальные функции для доступа к атрибуту с именем $attribute
. Функция __get ()
просто возвращает значение атрибута $attribute
, а функция __set ()
присваивает ему новое значение.
Заметьте, что функция __get ()
принимает один параметр — имя атрибута — и возвращает значение этого атрибута. Аналогично, функция __set ()
принимает два параметра — имя атрибута и новое значение, которое должно быть ему присвоено.
Мы не должны вызывать эти функции напрямую. Два символа подчеркивания в начале имени функции означают, что они имеют в РНР специальное назначение подобно функциям __construct ()
и __destruct ()
.
Рассмотрим, как работают эти функции. Если вы создаете экземпляр класса:
$a = new classname ();
то можете затем использовать функции __get()
и __set()
для проверки и установки любого атрибута.
Показанный ниже оператор:
$a -> $attribute = 5;
приведет к неявному вызову функции __set()
с передачей ей attribute
в качестве значения параметра $name
и 5 в качестве значения параметра $value
. Внутри функции __set ()
вы должны обеспечить все необходимые проверки на ошибочные значения.
Функция __get ()
работает аналогичным образом. Если где то в коде присутствует ссылка на атрибут:
$a -> $attribute
осуществляется неявный вызов функции __get ()
с передачей ей attribute
в качестве значения параметра $name. Это приведет к возврату функцией __get ()
значения атрибута.
На первый взгляд этот код может показаться не особо ценным. Возможно, что в том виде, в каком он приведен, это и так, но причина использования функций доступа проста: в этом случае обращение к конкретному атрибуту будет выполняться в рамках только одного раздела кода.
При наличии только одной точки обращения можно реализовать проверку того, что сохраняться будут только имеющие смысл данные. Если впоследствии выяснится, что значение атрибута $attribute
может лежать в диапазоне между 0 и 100, можно только один раз добавить несколько строк кода и выполнять проверку перед тем, как разрешать изменения. Теперь функции __set ()
можно придать такой вид:
function __set ($name, $value)
(
if ($name = 'attribute' && $value >= $value <= 100)
$this -> attribute = $value;
}
При наличии единственной точки доступа можно легко изменять реализацию, лежащую в основе кода. Если по какой-либо причине требуется изменить способ хранения атрибута Sattribute
, функции доступа позволяют делать это, изменяя код только в одном месте.
Может выясниться, что вместо хранения Sattribute
в виде переменной необходимо получать ее из базы данных, вычислять текущее значение при каждом ее запросе, получать значение, исходя из значений других атрибутов, или кодировать данные в виде более короткого типа данных. Какое бы изменение ни требовалось выполнить, можно просто изменить функции доступа. Это не окажет влияния на другие разделы кода до тех пор, пока функции доступа будут продолжать принимать или возвращать данные, ожидаемые другими частями программы.
Комментарии(0)
Для добавления комментариев надо войти в систему и авторизоватьсяКомментирование статей доступно только для зарегистрированных пользователей:Зарегистрироваться