Объектно-ориентированное программирование
Delphi в качестве внутреннего языка программирования использует Object Pascal. Главное отличие Object Pascal от языка программирования Pascal в том, что Object Pascal работает с объектами. Библиотека визуальных компонентов (VCL) представляет из себя иерархию классов, написанных на языке Object Pascal и объединенных в интегрированной среде разработки (IDE) Delphi. Разработчики могут создавать собственные объекты и классы и обмениваться ими. Это дает возможность достаточно быстро создавать приложения. Используя палитру компонентов и инспектор объектов, разработчик может размещать на формах компоненты и изменять их свойства без написания какого-либо кода.
Итак, что же такое объект? Класс - это тип данных, который включает в себя данные и операции над данными, а объект - это экземпляр какого-либо класса. Таким образом класс - это описание (тип), а объект - это то, что создано в соответствии с этим описанием. До создания объектно-ориентированных языков программирования данные и операции над данными рассматривали как отдельные элементы. Что такое объект, достаточно просто можно понять, если раньше вам приходилось работать с записями в Pascal. Записи состоят из областей, которые содержат данные разных типов (каждая область записи имеет собственный тип данных). Записи были созданы для облегчения работы с элементами, которые содержат различные типы данных.
Объекты - это тоже хранилища разных типов данных. Данные объекта называются полем (field) и аналогичны полям записи. Но объекты, в отличие от записей, содержат еще процедуры и функции, которые применимы к полям данного объекта. Эти процедуры и функции называются методами (methods). Изменять поля объекта также можно через свойства (properties) объекта. Каждое свойство объекта в Delphi представляет собой поле и методы, которые позволяют считывать значение поля и задавать его (так называемые методы доступа). Свойства можно изменять в процессе разработки приложения без написания какого-либо кода с помощью инспектора объектов. Если доступ к полям объекта извне осуществляется только посредством методов доступа, такое свойство объекта называется инкапсуляцией. В дополнение к инкапсуляции, объектно-ориентированное программирование характеризуется еще свойствами наследования и полиморфизма. Наследование обозначает, что объекты могут получать свои свойства и методы от других объектов (которых называют в данном случае предками). Объекты-наслед
ники берут от предков все свойства, методы и поля. Эти свойства, методы и поля в объекте-наследнике могут сохраняться в неизменном виде, либо могут быть изменены. Кроме того, объекты-наследники имеют в своем составе дополнительно новые поля, методы или свойства. Полиморфизм подразумевает, что всегда вместо метода предка может быть подставлен метод объекта-потомка и будет вызван метод фактически переданного объекта (при этом, естественно, методы потомка и предка могут иметь совершенно разное содержание).
Объекты в Delphi динамически занимают блоки памяти, структуру которых определяет их класс. Каждый объект является уникальным экземпляром своего класса и имеет все методы класса.
Типичное определение нового класса выглядит следующим образом:
type Имя класса = class (Класс-предок)
{Список состава класса} private
{частные описания} protected
{защищенные описания} public -
(общедоступные описания} published
{опубликованные описания} end;
где имя класса - любое корректное имя (выбирается произвольно), Класс-предок - название класса, наследником которого является создаваемый класс, Список состава класса - содержит свойства и методы нового класса. Для каждого элемента класса можно установить разную видимость. Для этого предназначены четыре ключевых слова: private, protected, public и published. Видимость элемента класса определяет, где в программе и как будет виден данный элемент класса. Минимальная видимость элемента класса задается ключевым словом private. Ключевое слово protected задает средний уровень видимости, a public и published - наивысшую степень доступности. Например, строка
published property Color: TColor read GetColor write SetColor;
определяет свойство color для некоего класса, которое является опубликованным (published), т. е. имеет наивысшую видимость.
Если перед описанием элемента класса не ставится ключевое слово, определяющее его степень видимости, то считается, что видимость элемента такая же, как и у предыдущего элемента класса, например:
published property Color: TColor read GetColor write SetColor; property BackColor: TColor read GetBackColor write SetBackColor;
В данном примере оба свойства - Color и BackCoior - являются опубликованными.
Рассмотрим все четыре ключевых слова более подробно.
- Private (частные) - определяет элементы класса, которые не видны вне модуля, в котором был объявлен класс, содержащий эти элементы. Другими словами, частные методы не могут быть вызваны из других модулей, а частные поля или свойства не могут быть считаны или изменены из других модулей.
- Protected (защищенные) - определяет элементы класса, которые видны только внутри модуля, где определен класс, содержащий эти элементы, а также внутри других модулей, где присутствуют классы-потомки данного класса.
- Public (общедоступные) - определяет элементы класса, которые видны в любом месте программы и из любых модулей, в которых виден сам класс.
- Published (опубликованные) - определяет элементы класса, имеющие ту же видимость, что и public-элементы. Единственное отличие заключается в том, что опубликованные элементы порождают информацию о типе времени выполнения (RTTI). Благодаря данной информации, Delphi может осуществить проверку принадлежности элементов объекта тому или иному классу. Delphi использует RTTI для доступа к значениям свойств при сохранении и загрузке файлов форм (*.DFM), чтобы иметь возможность отобразить свойства в инспекторе объектов и ассоциировать конкретные методы с конкретными свойствами. Все методы классов могут быть опубликованы, за исключением перегруженных (overload) методов, имеющих одинаковые имена.
Кроме свойств и методов, определение нового класса может содержать список интерфейсов (interfaces), поддерживаемых данным классом (подробно об интерфейсах см. вторую главу книги).
В Delphi имеется понятие абстрактного класса. Абстрактный класс описывает несуществующий объект. Он нужен для того, чтобы описать некоторые фундаментальные свойства и методы объектов, которые создаются из абстрактного класса. Все объекты в Delphi созданы из абстрактного класса TObject. Класс TObject - предок многих простых классов. Он объединяет в себе основные функции, которые свойственны всем объектам Delphi. Класс TObject обеспечивает:
- возможность создания, уничтожения и управления экземплярами объектов, а также резервирование памяти и ее освобождение после уничтожения экземпляра;
- поддержку информации об объектах и типах; - поддержку обработки сообщений.
Итак, все классы в Delphi - потомки класса TObject. Класс называется прямым потомком класса TObject, если он произведен непосредственно от класса TObject. Класс называется косвенным потомком от класса TObject, если он произведен от класса, являющегося прямым или косвенным потомком класса TObject (т. е. произведен от промежуточного класса).
Примечание
В другой литературе можно встретить названия дочерний класс и класс-потомок. Дочерний класс - это прямой потомок, а класс-потомок - это косвенный потомок в терминологии данной книги.
Если при создании нового класса (о создании классов читайте во второй части книги) не указывается родительский класс, то считается, что родитель - класс TObject.
Все компоненты в библиотеке визуальных компонентов созданы из абстрактного класса TComponent. Компоненты являются объектами, свойства которых разработчик может изменять во время создания приложения. Класс TComponent включает в себя наиболее общие свойства и методы компонентов, такие как:
- возможность включать компонент в палитру компонентов и работать с ним во время разработки приложения;
- способность быть владельцем других компонентов или быть управляемым другими компонентами;
- возможность обмена данными с файлами и потоками;
П возможность служить оболочкой элементов ActiveX и других объектов.
Визуальные компоненты (которые отображаются на экране монитора во время работы приложения), такие как TForm и TSpeedButton, называются элементами управления и их предком является абстрактный компонент
TControl.
На рис. 1.19 представлена упрощенная диаграмма иерархии визуальных компонентов. На этой диаграмме изображены несколько компонентов, являющихся элементами управления и имеющих в качестве предка компонент
TControl.
Несмотря на свое название, библиотека визуальных компонентов состоит по большей части из невизуальных объектов. Во время создания приложения разработчик может размещать на формах невизуальные компоненты (они не будут отображаться во время запуска приложения) и изменять их свойства в точности так же, как при работе с визуальными объектами.
Кроме вышеописанных классов, в число базовых классов в Delphi входят
TWinControl, TCustomEdit И TBaseArray.
Рис. 1.19. Упрощенная диаграмма иерархии библиотеки визуальных компонентов (VCL) Delphi
К основным понятиям объектной модели Delphi относятся так называемые области видимости объектов. Область видимости объекта определяет ту часть кода Object Pascal, в которой доступны его (объекта) свойства и методы без явного указания объекта. Когда вы пишите код, который находится в области видимости объекта, вам необязательно указывать имя этого объекта для доступа к его свойствам и методам. Например, когда вы помещаете новую кнопку на форму, то вы можете обращаться к свойствам и методам формы в обработчиках событий кнопки без указания имени формы (листинг 1.4).
Листинг 1.4
procedure TForml.ButtonlClick(Sender: TObject); begin
Color := clGray;
Buttonl.Color := clTeal; end;
Примечание
В листинге 1.4 строка, задающая цвет кнопки Buttonl, может не работать в некоторых версиях Delphi. Автор проверял работоспособность данного кода в Delphi 5 версии Enterprise.
На приведенном выше в листинге 1.4 обработчике события кнопки Onclick строка
Color := clGray;
равносильна строке
Forml.Color := clGray;
Вам не нужно указывать название формы, т. к. метод Button1Click является частью объекта TForm1.
Вторая строка листинга 1.4 изменяет свойство объекта Buttonl, а не формы, поэтому нуждается в указании имени объекта.
Delphi создает отдельный файл модуля для каждой формы. Поэтому, для того чтобы иметь доступ из одного модуля к объекту, расположенному в другом модуле, вам потребуется указывать полное имя объекта, например:
Form2.Buttonl.Color := clTeal;
Точно так же можно вызывать на исполнение методы объектов, расположенных на другой форме (в другом модуле), например:
Form2.Editl.Clear;
Кроме всего вышеописанного, для использования объектов модуля Form2
(unit2) в модуле формы 1 (unit1) вам потребуется прописать в разделе uses
модуля uniti модуль Unit2:
implementation
uses Unit2;
Содержание раздела