ProfiPHPProfiPHP
  1. Главная
  2. Самоучитель PHP 7
  3. Классы и объекты

Классы и объекты

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

Объектно-ориентированное программирование наряду с предопределенными типами (такими как integer, boolean, double, string) позволяет формировать собственные абстрактные пользовательские типы переменных - классы. Экземпляры классов или переменные их типа называются объектами. Создавая собственные типы данных, можно оперировать не машинными терминами (переменная), а объектами реального мира, поднимаясь тем самым на новый абстрактный уровень.

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

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


В языке программирования PHP класс объявляется при помощи ключевого слова class, после которого следуют уникальное имя класса и тело класса в фигурных скобках. Название класса не зависит от регистра и может содержать любое количество цифр, букв и символов подчеркивания, однако не может начинаться с цифры. Стандарт кодирования PSR требует, чтобы имя класса должно быть объявлено с использованием так называемой СаmеlСаsе: каждое слово начинается с большой буквы, между словами нет разделителей. Более подробно можно узнать из статьи Стандарты, стили и правила оформления кода PHP.
<?php
class MyClass
{
// Переменные класса
}
РНР позволяет включать скрипты в документ при помощи тегов <?php и ?>. Один документ может содержать множество включений этих тегов, однако класс должен объявляться в одном неразрывном блоке <?php и ?>. Не удастся механически разбить класс и при помощи инструкции Include или Require.

В теле класса могут быть объявлены переменные, которые называются переменными класса. Например, для задания точки координат можно создать класс Map, содержащий две координаты и :
<?php
class Map
{
public $x;
public $y;
}
В скрипте возможно лишь один раз определить класс. Попытка повторного определения класса приведет к генерации сообщения об ошибке "Fatal error: Cannot declare class Map, because the name is already in use". Данную ошибку довольно легко диагностировать, то есть оба класса находятся в одном и том же файле. Однако на практике под каждый класс выделяется отдельный файл, а в большом проекте, состоящей из десятков классов, использование инструкций подключения файлов может привести к ситуации, когда один и тот же файл включается повторно, что приведет также к ошибке. Ситуация может усложняться тем, что внутри включаемых файлов могут быть расположены другие конструкции, включающие другие файлы. Чтобы решить проблему с повторным определением классов необходимо использовать Include_once или Require_once. Их отличие от оригинальных инструкций состоит в том, что они включают файл только один раз, попытки повторного включения файла игнорируются.

Создание объекта


После создания класса можно переходить к созданию объекта данного класса путем объявления при помощи ключевого слова new, за которым следует имя класса. Стандарт кодирования PSR рекомендует хранить код класса и использующий его код в разных файлах. Чтобы воспользоваться классом, файл, содержащий его определение, следует включить при помощи инструкции require_once:
<?php
require_once 'map.php';
$map = new Map;
$map->x = 1;
$map->y = 2;
echo $map->x; // 1
Объект $map класса Map создается при помощи ключевого слова new. Для обращения к переменным объекта и , следует воспользоваться специальным оператором "->". В отличие от стандартных переменных РНР, символ $ после -> при обращении к переменным объекта не указывается. После инициализации объекта создается обычная переменная $map из специфичными свойствами. Как и любой другой переменной, объекту можно присваивать новое значение.
<?php
require_once 'map.php';
$map = new Map; // object
$map = 'str'; // string(3)
В данном примере объекту $map присваивается строковое значение, и он становится переменной строкового типа.

Как и обычная переменная, объект существует до конца времени выполнения скрипта или пока не будет уничтожен явно при помощи конструкции Unset. Использование конструкции Unset может быть полезным, если объект занимает большой объем оперативной памяти, и ее следует освободить, чтобы не допустить переполнения.

Спецификаторы доступа


Переменные класса объявляются при помощи спецификаторов public, private или protected, которые указывают на доступы к переменным объекта извне. Открытые члены класса объявляются спецификатором доступа public и доступны как внутри класса, так и внешнему по отношению к классу коду. Закрытые методы и члены класса объявляются при помощи спецификатора private и доступны только в рамках класса. Спецификатор protected используется при наследовании.
<?php
class PrivateMap
{
public $x;
private $y;
}
// Объявляем объект класса PrivateMap
$map = new PrivateMap;

// Присваиваем значения переменным объекта
$map->x = 1;
$map->y = 2; // Fatal error: Uncaught Error: Cannot access private property PrivateMap
В данном примере класс содержит открытую переменную и закрытую . Обращение к закрытому члену класса завершится ошибкой "Fatal error: Uncaught Error: Cannot access private property PrivateMap".

Статические переменные класса


Каждый объект обладает своим набором переменных, независимых от других объектов. Но возможно создать статические переменные на уровне класса, которые объявляются при помощи ключевого слова static. Особенностью таких переменных является возможность их инициализации прямо в классе при объявлении:
<?php
class MyStatic
{
public static $staticvar = 50;
}
Обращаться к таким переменным можно без создания объектов при помощи оператора разрешения области видимости "::":
echo MyStatic::$staticvar; // 50

Ссылки на переменные


Если присваивать переменным одинаковые значения при помощи оператора получаются две независимые переменные:
<?php
$first = $second = 1;
$first = 2;
echo $second; // 1
При работе с объектами ситуация совершенно другая. Оператор присваивания = не приводит к созданию новой копии объекта: и старый, и новый объект указывают на одну и ту же область памяти:
<?php
require_once 'map.php';

$first = new Map;
$first->x = 3;
$first->y = 3;

$second = $first;
$second->x = 5;
$second->y = 5;
echo "x: {$first->x}, y: {$first->y}";
Присвоение новых значений переменным одного объекта приводит к тому, что эти же значения получает и второй объект. То есть переменные $first и $second ссылаются на один и тот же объект.

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

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


Если необходимо создать копию текущего объекта, используется специальная операция - клонирование. Она выполняется при помощи ключевого слова clone, которое располагается непосредственно перед объектом клонирования:
<?php
require_once 'map.php';

$first = new Map;
$first->x = 3;
$first->y = 3;

$second = clone $first;
$second->x = 5;
$second->y = 5;

echo "x: {$first->x}, y: {$first->y}"; // x: 3, y: 3

Добавить комментарий

Имя:
Текст комментария: