Классы и объекты
Давайте подведем предварительные итоги. Во-первых, мы рассмотрели, что такое встроенные типы данных, какие они бывают, в чем состоит их различие, как создавать переменные этих типов и т. д. Во-вторых, мы научились создавать собственные типы данных (записи), а также пользовательские процедуры и функции. Это уже достаточно весомый багаж знаний, однако остался еще небольшой, но очень важный раздел, посвященный таким понятиям объектно-ориентированного программирования, как классы и объекты (экземпляры классов).
В самом упрощенном понимании объект – это какая-то вещь или материальная сущность реального мира. Оглянитесь вокруг, и вы увидите, что наш мир состоит из бесконечного числа объектов: стол, машина, клавиатура компьютера, дом, человек и т. д. (более того, даже мир – это объект). Если приглядеться, то каждый объект имеет свойства (машина черного цвета) и операции, которые выполняются над этими свойствами (ту же машину можно перекрасить в экзотический металлик). Почти аналогично обстоит дело с объектами в абстрактном мире программ. Например, в качестве объекта можно рассматривать файл, в качестве свойства – его размер или имя, а в качестве операций – чтение или запись.
Рассмотрим еще один пример объекта в абстрактном мире программ – переменную author типа Person co свойствами name и birthday. Итак, есть объект и есть свойства, что же является операцией в данном случае? Любая пользовательская процедура или функция, изменяющая свойства объекта author или просто работающая с ними. Например, процедура инициализации полей записи или процедура вывода на экран значений полей.
А теперь представьте, что код программы испещрен как процедурами, которые относятся к работе с записью author, так и функциями, относящимися к другим переменным, которых тоже не мало. Совсем нетрудно будет заблудиться в подобном хаосе и применять нужную функцию к неверным данным или, наоборот, необходимые данные подставлять не в ту функцию. Возникает естественное желание объединить данные и способы их обработки в одно целое – так, чтобы было ясно, какие процедуры предназначены для обработки каких данных. Таким образом, мы вплотную подошли к центральным понятиям объектно-ориентированного программирования – понятиям инкапсуляции и класса.
Объектно-ориентированное программирование (ООП) – наиболее популярная в настоящее время методология программирования, являющаяся развитием структурного программирования. Центральной идеей ООП является инкапсуляция, т. е. структурирование программы на модули особого вида, объединяющие данные и процедуры их обработки (вот оно, решение всех проблем!), причем внутренние данные модуля могут быть обработаны только предусмотренными для этого процедурами. В разных вариациях ООП этот модуль называют по-разному: класс, абстрактный тип данных, кластер и др. В VBA принято называть этот модуль модулем класса, или просто классом. Каждый такой класс имеет внутреннюю часть, называемую реализацией, и внешнюю – интерфейс.
Класс, таким образом, представляет собой новый тип данных, позволяющий создавать новые переменные этого типа (объекты) (иногда их еще называют экземплярами класса) и вести связанные с ними процедуры и функции. Программист описывает класс как сложный структурированный тип, состоящий из элементов, которые могут быть как собственно данными, т. е. значениями определенного типа данных, так и функциями, реализующими операции над элементами-данными. Элементы-данные называются свойствами класса, элементы-функции – методами класса. Такое описание служит шаблоном для создания в программе конкретных экземпляров (объектов) данного класса, имеющих свои конкретные имена.
В случае с записью Person при добавлении к ней двух процедур (persinit, persPrint) мы фактически получили класс, одним из объектов которого будет author. Доступ к свойствам и методам объекта осуществляется (как и в случае с записью) посредством точечной нотации. Например, для того, чтобы вывести на экран свойства объекта author с помощью метода Print, необходимо ввести в программу выражение author.Print ().
Помимо инкапсуляции, ООП VBA характеризуется еще одним немаловажным свойством – встраиванием. Встраивание – это механизм порождения новых классов с использованием существующих.
Пусть построен класс А, тогда при объявлении нового класса В его свойствами могут быть объекты класса А. В этом случае говорят, что класс А встроен в класс В, и класс А является родителем, а класс В – потомком. Встраивание – транзитивное отношение, т. е. можно создать произвольно длинную цепочку вложенных объектов, образующих иерархию родителей и потомков. Так, в новый класс С можно встроить объект класса В, который является объектом класса А.
Для приложений Office XP характерна ситуация, когда необходимо указать шесть-восемь уровней вложенности, чтобы добраться до нужного объекта. Например, чтобы скрыть панель инструментов Стандартная, выполните следующий оператор присваивания:
Outlook.Application.ActiveExplorer.ShowPane(olOutlookBar,
True
)
Механизм встраивания очень удобен и естественен. Прародитель семейства классов может задавать некоторые фундаментальные свойства и методы, а многочисленные потомки, имея родительские корни (свойства и методы), привносят собственные узкоспециальные свойства и методы.
Например, создавая класс Book со свойством Author класса Person, мы не только используем фундаментальные свойства и методы класса Person, но и вводим собственные свойства (title) и методы.
Наряду со встраиванием, существует еще один способ использования существующих классов при создании новых, он называется наследование. При наследовании указывается, что вновь создаваемый класс В на основе класса А содержит все (или некоторые) методы и свойства класса А, а также свои собственные методы и свойства. Например, на основе класса Person можно определить класс Author, который содержит все методы и свойства класса Person, а также свои собственные, например список книг данного автора.
Перейдем теперь от теоретического описания канонов ООП к практике их применения в VBA и начнем с синтаксиса. Синтаксически классы в VBA оформляются в виде специальных модулей классов (имя класса – это имя модуля), где в разделе Declarations помещается описание свойств (переменных) класса, а дальше идет описание методов (процедур) класса. Синтаксически описания свойств и методов практически не отличаются от описания обыкновенных переменных и процедур. Случаи отличия или особенностей употребления будут оговорены отдельно.