Классы и объекты Эта глава не предназначена для того, чтобы изучать по ней основы объектно-ориентированного программирования (ООП). Мы лишь хотим дать представление о том, как основные идеи ООП реализованы в языке Perl. Начнем с краткого обзора этих идей. В основе ООП лежат понятия класса и объекта. Эти понятия тесно связаны друг с другом. Класс представляет собой сочетание структуры данных и тех действий, которые можно выполнить над этими данными. Данные называют свойствами, а действия — методами. Совмещение в классе структуры данных и действий над ними называют инкапсуляцией. Объект является экземпляром класса. Свойства объекта обусловлены его принадлежностью к определенному классу. Понятия "объект" и "класс" отражают два различных вида иерархий, которые можно обнаружить в любой достаточно сложной системе. Рассмотрим пример. Персональный компьютер является сложной системой. Жесткий диск — составная часть этой системы. Другими ее частями являются центральный процессор, память и т. д. Можно сказать, что жесткий диск — это часть структурной иерархии под названием "персональный компьютер". С другой стороны, жесткий диск является абстракцией, обобщением свойств, присущих всем жестким дискам, и этим он отличается, например, от гибкого диска, рассматриваемого как абстракция, обобщающая свойства всех гибких дисков. В типовой иерархии жесткие диски Quantum — это особый тип жестких дисков, жесткие диски Quantum Fireball EL — особый тип жестких дисков Quantum, жесткие диски Quantum Fireball EL объемом 5,1 Гбайт — особый тип жестких дисков Quantum Fireball EL и т. д. В данной аналогии абстрактный жесткий диск является базовым классом, жесткие диски фирмы Quantum образуют подкласс класса жестких дисков, жесткие диски Quantum Fireball EL — подкласс класса жестких дисков фирмы Quantum и т. д. Подкласс называют также производным классом или классом-потомком. Для него класс, расположенный выше в иерархии, является базовым, подклассом или родительским классом. В нашем примере объект (конкретный жесткий диск) является составной частью структуры под названием "персональный компьютер", и обладает своими свойствами в силу принадлежности к определенному типу дисков Quantum Fireball EL 5,1 Гбайт, отличающемуся по своим характеристикам от других типов жестких дисков. Действие, которое можно выполнить над данными, определяет метод. Он представляет собой подпрограмму. Различают методы класса и методы объекта. Последние могут применяться к любому объекту класса. Методы класса, называемые также статическими методами, не зависят от отдельного экземпляра, они применяются к целому классу как к отдельному объекту. Для создания объектов применяются специальные статические методы, называемые конструкторами. Для корректного удаления объектов используются специальные методы, называемые деструкторами. Термин наследование в ООП обозначает способность классов наследовать свойства и методы у своих родительских классов. Термин полиморфизм в ООП обозначает свойство класса-потомка переопределять методы родительского класса. Инкапсуляция, наследование, полиморфизм — базовые понятия, лежащие в основе объектно-ориентированного программирования. Объектно-ориентированный подход возник в результате непрекращающихся попыток человека преодолеть сложность окружающего мира, проявляющуюся в любых областях деятельности. Он предлагает более естественный способ разделения сложной задачи на ряд более простых, используя понятие объекта, сочетающего данные и действия над ними. Он также позволяет экономить усилия, связанные с написанием программного кода, так как однажды созданные методы не нужно переписывать — они просто наследуются производными классами. Идея повторного использования кода в своем развитии проходит ряд этапов: подпрограмма, библиотека, модуль, класс. В этой главе мы рассмотрим, каким образом основные концепции объектно-ориентированного программирования реализованы в языке Perl. В языке Perl нет специального синтаксиса для описания классов, объектов или методов. Для их реализации используются уже знакомые нам синтаксические конструкции. Класс в Perl представляет собой пакет, объект является ссылкой, а метод — обычной подпрограммой. В качестве пакета каждый класс имеет собственное изолированное пространство имен и таблицу символов, реализованную в виде хеш-массива. К переменным класса можно обращаться, используя их квалифицированные имена, содержащие в качестве префикса имя класса, за которым следуют два двоеточия, например, $CLASSNAME: :var. Для того чтобы пакет стал классом, в нем нужно определить специальную подпрограмму — конструктор, которая используется для создания отдельных экземпляров класса — объектов (см. здесь). Объект в Perl представляет собой просто ссылку, но не любую, а связанную с определенным классом. Тип ссылки можно определить при помощи функции ref EXPR, которая, рассматривая свой аргумент как ссылку, возвращает символическое обозначение ее типа. Для встроенных типов Perl используются следующие символические обозначения:
Для ссылки-объекта функция ref () возвращает имя класса, к которому этот объект принадлежит. Обычная ссылка становится объектом после ее "посвящения" в члены класса при помощи функции bless REF [, CLASSNAME] Слово "bless" в английском языке имеет значение "освящать, благословлять". В данном контексте его можно перевести как "посвящать" или "санкционировать". Функция bless REF санкционирует принадлежность субъекта ссылки REF к классу CLASSNAME. Она возвращает ссылку на этот субъект, но уже другого типа — CLASSNAME (напомним, что в главе 9 субъектом ссылки мы условились называть то, на что она указывает, т. е. собственно структуру данных некоторого типа). Она связывает обычную ссылку с именем класса. Если имя класса не задано, то используется имя текущего класса. После выполнения функции bless ок созданному ей объекту можно обращаться, используя его квалифицированное имя $CLASSNAME: :REF. Сказанное иллюстрируется следующим примером. $h = { }; • print("тип переменной \$h - ". ref($h), "\n"); bless($h, "MyClass"); print("тип переменной \$h - ". ref($h), "\n"); В результате будет выведен тип переменной $ref до и после вызова функции bless (): тип переменной $h — HASH тип переменной $h — MyClass Наследование в Perl отличается от наследования в других объектно-ориентированных языках программирования тем, что наследуются только методы. Наследование данных реализуется программистом самостоятельно. Наследование методов реализовано следующим образом. С каждым пакетом ассоциирован свой специальный массив @ISA, в котором хранится список базовых классов данного пакета. Таким образом, подкласс располагает информацией о своих базовых классах. Если внутри текущего класса встречается обращение к методу, не определенному в самом классе, то интерпретатор в поисках отсутствующего метода просматривает классы в том порядке, в котором они встречаются в массиве @ISA. Затем просматривается предопределенный класс UNIVERSAL. В нем изначально нет никаких явных определений, но автоматически содержатся некоторые общие методы, которые неявно наследуются всеми классами. В этом смысле класс UNIVERSAL можно считать базовым классом всех остальных классов. Если метод не найден ни в одном из просмотренных классов, они вновь просматриваются в том же порядке в поисках подпрограммы AUTOLOAD (см. здесь). Если таковая обнаружена, она выполняется вместо вызванного несуществующего метода с теми же параметрами. Квалифицированное имя несуществующего метода при этом доступно через переменную $AUTOLOAD. Поделитесь этой записью или добавьте в закладки | Полезные публикации |