На этом шаге мы рассмотрим особенности определения классов и объектов.
В языке Perl нет специального синтаксиса для описания классов, объектов или методов. Для их реализации используются уже знакомые нам синтаксические конструкции. Класс в Perl представляет собой пакет, объект является ссылкой, а метод - обычной подпрограммой.
В качестве пакета каждый класс имеет собственное изолированное пространство имен и таблицу символов, реализованную в виде хеш-массива. К переменным класса можно обращаться, используя их квалифицированные имена, содержащие в качестве префикса имя класса, за которым следуют два двоеточия, например, $CLASSNAME::var. Для того чтобы пакет стал классом, в нем нужно определить специальную подпрограмму - конструктор, которая используется для создания отдельных экземпляров класса - объектов.
Объект в Perl представляет собой просто ссылку, но не любую, а связанную с определенным классом. Тип ссылки можно определить при помощи функции ref EXPR, которая, рассматривая свой аргумент как ссылку, возвращает символическое обозначение ее типа. Для встроенных типов Perl используются следующие символические обозначения:
Для ссылки-объекта функция ref() возвращает имя класса, к которому этот объект принадлежит. Обычная ссылка становится объектом после ее "посвящения" в члены класса при помощи функции
bless REF [, CLASSNAME]
#! 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.
На следующем шаге мы приведем общие сведения о методах.