- •Класс как тип данных
- •Создание нового класса
- •Работа с классами
- •Создание объекта некоторого класса
- •Доступ к свойствам объекта
- •Доступ к методам
- •Создание нескольких объектов
- •Конструктор
- •Параметры по умолчанию
- •Старый способ создания конструктора
- •Перегрузка преобразования в строку
- •Инициализация и разрушение
- •Деструктор
- •Вопрос освобождения ресурсов
- •Описание деструктора
- •Алгоритм сбора мусора
- •Циклические ссылки
- •Проблема циклических ссылок
- •Задания для самостоятельного решения
Работа с классами
Предположим, что в программе каким-то образом уже описан некоторый класс. Так как класс - это, по сути, тип данных, мы должны иметь некоторый механизм для создания переменных, хранящих значение этого типа.
Создание объекта некоторого класса
Вспомните, как мы поступали при использовании стандартных типов:
// Создание переменной-числа
$number = 10.4;
// Создание строки
$str = "Some string";
/ / Создание массива
$arr = (1, 2, З);
При создании переменных, имеющих пользовательский тип данных (иными словами, при создании объектов класса), применяется ключевое слово new, за которым следует имя класса:
$obj = new MathComplex;
Теперь $obj хранит все данные класса - в частности, содержит внутри себя отдельные значения $re и $im.
Доступ к свойствам объекта
Как ранее говорилось, каждый объект имеет свой собственный набор ассоциированных с ним свойств (значений, или переменных) и множество методов (функций-членов).
Каждое свойство объекта доступно в программе по его имени. Можно присваивать значение свойству или получать его величину:
Как видите, доступ к свойству осуществляется при помощи оператора -> (стрелка, символ -, за которым идет > ).
Обратите внимание, что объект очень похож на ассоциативный массив. В самом деле, в массиве ведь тоже может храниться несколько значений, доступ к каждому из которых осуществляется по имени его ключа. У объектов вместо ключей - имена свойств, а для доступа к значениям используется оператор ->, а не квадратные скобки.
Доступ к методам
Вспомним, как мы вызывали "методы" встроенных типов данных:
Как видите, для встроенных типов используется либо операторная запись вызова "метода" (например, сложение), либо же функциональная (как будто вызывается функция). В РНР для вызова метода некоторого объекта используется оператор "стрелка".
Листинг 2 Вызов метода объекта. Файл call.php
Давайте посмотрим, что происходит, когда мы вызываем метод класса. Первым делом создается локальная переменная $this, которой присваивается то же значение, что было у $obj. То есть, в $this теперь хранится ссылка на объект, для которого вызывается метод. Далее РНР смотрит, какому классу принадлежит $obj (в нашем случае это MathCornplex), и находит функцию-член: MathCornplex: : add (). Функция вызывается, при этом $this, напомним, равен $obj. В итоге add() изменяет значения $obj->re и $obj->im (которые для нее выглядят как $this->re и $this->im. Их мы распечатываем следующей строчкой программы, уже после выхода из функции.
Как видите, вызов метода некоторого объекта автоматически предоставляет ему доступ к свойствам этого объекта посредством специальной переменной $this. При этом $this не нужно нигде объявлять явно, она появляется сама собой. Данная техника - ключевая особенность ООП.
Создание нескольких объектов
Мы только что передавали методу add () обыкновенное число. Однако, конечно, в качестве параметра функции можно указывать все, что угодно, например объект другого (или того же самого) класса. Листинг 3 иллюстрирует ситуацию. В учебных целях мы создадим еще один класс, MathCornplex1, немного изменив его метод add (). Кроме того, мы добавили еще и метод для получения строкового представления комплексного числа, чтобы не выводить его каждый раз вручную.
Листинг З Пример класса с методом. Файл Math/Complexl .php
Смотрите, мы явно указали перед параметром $у тип MathCornplex1. Это говорит РНР, что мы можем передавать в данную функцию только объекты этого класса, но не другого. Вот как может выглядеть корректное использование данного класса.
Листинг 4 Вызов метода объекта. Файл calll.php
ПРИМЕЧАНИЕ
В отличие от таких языков, как С++ и Java, в РНР не поддерживается создание в одном классе нескольких методов с одинаковым именем, которые бы различались только типами и количеством аргументов. Поэтому-то нам и пришлось создавать класс MathComplex1, а не просто добавить новую функцию add () с аргументом типа MathComplex в имеющийся класс.
