Шаг 139.
Классы и объекты

    На этом шаге мы рассмотрим особенности определения классов и объектов.

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

    В качестве пакета каждый класс имеет собственное изолированное пространство имен и таблицу символов, реализованную в виде хеш-массива. К переменным класса можно обращаться, используя их квалифицированные имена, содержащие в качестве префикса имя класса, за которым следуют два двоеточия, например, $CLASSNAME::var. Для того чтобы пакет стал классом, в нем нужно определить специальную подпрограмму - конструктор, которая используется для создания отдельных экземпляров класса - объектов.

    Объект в Perl представляет собой просто ссылку, но не любую, а связанную с определенным классом. Тип ссылки можно определить при помощи функции ref EXPR, которая, рассматривая свой аргумент как ссылку, возвращает символическое обозначение ее типа. Для встроенных типов Perl используются следующие символические обозначения:

    Для ссылки-объекта функция ref() возвращает имя класса, к которому этот объект принадлежит. Обычная ссылка становится объектом после ее "посвящения" в члены класса при помощи функции

   bless REF [, CLASSNAME]
Слово "bless" в английском языке имеет значение "освящать, благословлять". В данном контексте его можно перевести как "посвящать" или "санкционировать". Функция bless REF санкционирует принадлежность субъекта ссылки REF к классу CLASSNAME. Она возвращает ссылку на этот субъект, но уже другого типа - CLASSNAME (напомним, что субъектом ссылки мы условились называть то, на что она указывает, т.е. собственно структуру данных некоторого типа). Она связывает обычную ссылку с именем класса. Если имя класса не задано, то используется имя текущего класса. После выполнения функции bless() к созданному ей объекту можно обращаться, используя его квалифицированное имя $CLASSNAME::REF. Сказанное иллюстрируется следующим примером.
#! perl -w
$h = {};
print ("тип переменной \$h - ". ref($h), "\n");
bless ($h, "MyClass") ;
print ("тип переменной \$h - ". ref($h), "\n");
Текст этого примера можно взять здесь.

    В результате будет выведен тип переменной $ref до и после вызова функции bless() (рисунок 1):


Рис.1. Результат работы скрипта

Наследование в Perl отличается от наследования в других объектно-ориентированных языках программирования тем, что наследуются только методы. Наследование данных реализуется программистом самостоятельно.

    Наследование методов реализовано следующим образом. С каждым пакетом ассоциирован свой специальный массив @ISA, в котором хранится список базовых классов данного пакета. Таким образом, подкласс располагает информацией о своих базовых классах. Если внутри текущего класса встречается обращение к методу, не определенному в самом классе, то интерпретатор в поисках отсутствующего метода просматривает классы в том порядке, в котором они встречаются в массиве @ISA. Затем просматривается предопределенный класс UNIVERSAL. В нем изначально нет никаких явных определений, но автоматически содержатся некоторые общие методы, которые неявно наследуются всеми классами. В этом смысле класс UNIVERSAL можно считать базовым классом всех остальных классов.

    Если метод не найден ни в одном из просмотренных классов, они вновь просматриваются в том же порядке в поисках подпрограммы AUTOLOAD. Если таковая обнаружена, она выполняется вместо вызванного несуществующего метода с теми же параметрами. Квалифицированное имя несуществующего метода при этом доступно через переменную $AUTOLOAD.

    На следующем шаге мы приведем общие сведения о методах.




Предыдущий шаг Содержание Следующий шаг