Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование Часть 2 - Delphi

.pdf
Скачиваний:
24
Добавлен:
16.03.2015
Размер:
734 Кб
Скачать

11

Метод представляет собой процедуру или функцию, определенную в рамках класса,

и используемую для выполнения действий над полями. В разделе interface содержится объявление методов (при описании класса), а в разделе implementation записывается программный код. В отличие от обычных процедур и функций заголовки методов должны иметь составные имена, содержащие наименование классов. Внутри методов обращения к полям и другим методам выполняется как к обычным переменным и подпрограммам, без уточнения объекта.

Следуя логике объектно-ориентированного программирования, все мыслимые действия над полями объекта необходимо определять в виде правил – процедур и функций. Именно это в конечном итоге обеспечивает простоту и универсальность ООП,

так как описание каждого класса становится функционально завершѐнным на соответствующем уровне иерархии. Описание класса получается громоздким, но очень удобным для дальнейшего использования.

Наиболее полно стараются описать классы, расположенные на верхних уровнях иерархии. При этом можно не заботиться о том, что какой-либо метод не будет использован, так как код методов, к которым нет обращения в программе, компилятор не включает в exe-файл.

Type

TMyClass = class

Function MyFunc (aPar: Integer): Integer;

Procedure MyProc;

End;

Var

aObject: TMyClass;

...

Begin

...

aObject.MyProc;

...

end;

Методы класса могут перекрываться в потомках. Например:

Type

TParentClass = class

Procedure DoWork;

End;

12

TChildClass = Class (TParentClass)

Procedure DoWork;

End;

Потомки обоих классов могут выполнять сходную по названию процедуру DoWork,

но, в общем случае, будут это делать по-разному. Такое замещение методов называется статическим, так как реализуется компилятором.

Всостав любого класса входят два специальных метода – конструктор и деструктор.

Укласса TObject эти методы называются Create и Destroy, так же они называются в подавляющем большинстве его потомков. Обращение к конструктору должно предварять любое обращение к полям и некоторым методам объекта.

DiskGauge:=TDiskGauge.Create;

Конструктор создаѐт объект. Создание объекта включает выделение памяти и инициализацию полей. Распределив объект в динамической памяти, конструктор помещает адрес этой области памяти в переменную Self, которая автоматически объявляется в классе. Деструктор разрушает объект: очищает поля и удаляет объект из кучи (освобождает память):

DiskGauge.Destroy;

После вызова деструктора обращаться к полям и методам объекта нельзя.

Так как действия, выполняемые при создании и разрушении разных объектов, могут быть специфичными, то Object Pascal позволяет переопределить стандартные конструктор

Create и деструктор Destroy. Можно даже определить несколько конструкторов и деструкторов, выполняющих свою работу разными способами. Объявление конструкторов и деструкторов аналогично объявлению обычных процедур, только вместо слова procedure используются constructor и destructor.

Конструктор может иметь параметры, через которые передаются исходные значения полей. Конструктор может применяться к классу или объекту. При применении конструктора к классу выполняются действия:

выделяется в памяти место под объект;

выделенная память заполняется. Поля, содержащие указатели и объекты, получают значение nil. Числовые поля заполняются нулями. Строки задаются пустыми;

выполняются действия, определяемые конструктором;

ссылка на созданный объект возвращается в качестве значения конструктора. Тип возвращаемого значения совпадает с типом класса, использованного при вызове.

13

При применении конструктора к объекту новый объект не создаѐтся, происходит переинициализация полей существующего. В этом случае конструктор не возвращает никакого значения.

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

Вызов деструктора для несуществующего объекта недопустим, если это сделать, то произойдѐт ошибка. Чтобы освободить программиста от необходимости контролировать наличие объекта и его состояние (равен или нет nil), ввели предопределѐнный метод Free,

который следует вызывать вместо деструктора. Метод Free сам вызывает Destroy, но только если значение объекта не равно nil.

DiskGauge.Free;

Большинство конструкторов реализуют некоторые действия, необходимые для правильной работы объекта. Поэтому в конструкторе класса-потомка надо сначала вызвать конструктор родителя, а потом задать дополнительные действия. Вызов любого перекрытого метода родительского класса выполняется с помощью зарезервированного слова inherited.

Constructor TMyClass.Create(mmm:byte);

begin

inherited Create;

intfield:=mmm;

end;

Метод, объявленный в классе, в зависимости от вида может вызываться разными способами. Вид метода задаѐтся служебным словом (модификатором), которое указывается в описании класса после заголовка метода и отделяется от него точкой с запятой. Основные типы методов:

abstract – абстрактный;

virtual – виртуальный;

dynamic – динамический;

override – перекрывающий;

Методы принято разделять на обычные (статические) и динамические. При обращении к обычному методу компилятор точно знает класс, которому данный метод принадлежит.

14

В Object Pascal чаще используется динамическое замещение методов на этапе выполнения программы. Для этого метод, замещаемый в родительском классе, должен объявляться как динамический (с директивой dynamic) или виртуальный (virtual). В

производных классах (потомках) виртуальный и динамический методы перекрываются с использованием слова override. Перекрывающий метод должен иметь точно такой же список параметров, что и перекрываемый. Суть динамического замещения методов в том,

что они вызываются по фактическому типу экземпляра. Работа виртуальных методов основана на механизме позднего связывания, в отличие от раннего связывания,

характерного для обычных методов. Позднее связывание основано на вычислении адреса вызываемого метода при выполнении программы. Адрес вычисляется по хранящемуся в каждом объекте описателю типа. Виртуальные методы позволяют в полной мере реализовать идею полиморфизма.

Разница между виртуальным и динамическим методами заключается в особенностях создаваемых таблиц и, как следствие, в разной скорости работы. Встретив метод,

объявленный как виртуальный или динамический, компилятор создаѐт таблицу DMT

(Dinamic Method Table) или VMT (Virtual Method Table) и помещает в неѐ адреса точек входа соответственно динамического или виртуального методов. При каждом обращении к замещаемому методу компилятор вставляет код, позволяющий извлечь адрес точки входа в подпрограмму из той или иной таблицы. Когда в классе-потомке встречается метод, объявленный с директивой override, компилятор создаст код, который на этапе прогона программы поместит в родительскую таблицу точку входа метода класса-

потомка, что позволит родителю выполнить нужное действие с помощью нового метода.

Таблица динамических методов содержит адреса только тех методов, которые объявлены как dynamic в данном классе, в то время как таблица VMT содержит адреса виртуальных методов не только данного метода, но и всех его родителей. Большая по размеру таблица

VMT обеспечивает более быстрый поиск. При использовании динамического метода программа сначала просматривает таблицу DMT у объекта, а затем у его родительского класса и так далее, пока не будет найдена нужная точка входа.

При построении иерархии классов часто возникает ситуация, когда работа виртуального метода в базовом классе неизвестна и наполняется содержанием только в потомках. В этом случае метод объявляется абстрактным. После слова virtual

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

Абстрактный метод подразумевает конкретное действие, а не способ его реализации.

Реализацию такие методы получают в наследниках.

15

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

Например, для разных геометрических фигур можно определить единые методы show, hide, moveto и абстрактный метод draw. Метод draw для каждой фигуры реализуется по-разному.

2.6. Управление доступом к классу

Существует три типа пользователей класса:

сам класс (методы класса могут обращаться к другим методам и данным класса);

обычные пользователи, то есть программы пользователя;

производные классы (методы производного класса могут обращаться к методам или данным базового класса).

Каждый пользователь обладает разными привилегиями доступа. Уровни доступа задаются ключевыми словами private, public, protected. Приватные члены класса,

объявленные в секции private, имеют самую ограниченную область действия. Они доступны только внутри методов данного класса и подпрограмм, находящихся в том же модуле. Элемент, объявленный как private, недоступен даже ближайшим потомкам класса,

если они размещены в других модулях. Обратите внимание, что приватные данные видимы, но недоступны. Такой контроль введен для предотвращения случайного доступа к данным или внутренним функциям, то есть в целях уменьшения ошибок при разработке программ, но не для предотвращения «взлома».

Ко всему, что объявлено в секции public, разрешен неограниченный доступ. В

частности, можно все содержимое класса объявить общедоступным и манипулировать им,

как заблагорассудится. При определении класса часть методов, свойств и полей можно скрыть от пользователя, но сделать доступными для производных классов, поместив их в секцию с ключевым словом protected. Элементы описания, размещѐнные в защищѐнной секции доступны только методам самого класса и любым его потомкам, независимо от того, находятся они в том же модуле, или нет.

Кроме перечисленных выше секций есть ещѐ одна – published. Правила видимости у этой секции такие же, как у public. Особенность в том, что для элементов, помещѐнных в эту секцию, генерируется информация, позволяющая превращать их в компоненты. Те свойства, которые должны быть доступны в Инспекторе объектов, обязательно надо поместить в эту секцию. Секция published используется при разработке компонентов.

По умолчанию (без указания типа секции) секция считается объявленной как published. Такая секция помещается в самом начале объявления класса любой формы и

16

продолжается до первой объявленной секции, в неѐ Object Pascal помещает описания

расположенных на форме компонентов.

3.РАЗРАБОТКА ПРИЛОЖЕНИЙ В СРЕДЕ ВИЗУАЛЬНОГО ПРОГРАММИРОВАНИЯ DELPHI

3.1. Проект и управление проектом

3.1.1. Проект Delphi

Всреде Delphi разрабатывается проект – набор файлов, из которых состоит

приложение. Рекомендуется файлы, относящиеся к проекту, хранить в отдельной папке.

В любой проект входит, по крайней мере, шесть файлов:

project1.dpr – главный файл проекта, формируется системой при создании нового приложения;

unit1.pas – первый модуль (unit) программы, который автоматически появляется в начале работы;

unit1.dfm – файл описания формы, используется для сохранения информации о внешнем виде главной формы;

project1.res – файл ресурсов, в нѐм хранятся иконки, растровые изображения,

курсоры. Как минимум, содержит иконку приложения;

project1.dof – файл опций, является текстовым файлом для сохранения установок,

связанных с данным проектом (например директив компилятора);

project1.cfg – файл конфигурации, содержит информацию о состоянии среды.

Кроме того, к проекту могут относиться файлы с картинками, видеофрагментами,

звуками, файлы справочной системы и т.п. Однако перечисленными элементами управляет сам программист. Если сохранить проект под другим именем, то кроме файла проекта изменят название и файлы с расширением res, dof и cfg. Если изменить имя файла модуля (.pas), то изменится и имя файла описания формы ( .dfm ).

Имена, данные системой по умолчанию, можно изменить. Хорошим стилем программирования считается использование имѐн, несущих смысловую нагрузку.

После компиляции программы получаются файлы с расширениями: dcu – скомпилированные модули;

exe – исполняемый файл;

~pas, ~dfm и т.п. – backup файлы (предыдущие версии).

Помимо модулей, связанных с формой, можно создавать отдельные модули, которые оформляются по обычным правилам языка Object Pascal (Delphi), сохраняются в

17

отдельных файлах. Имена этих модулей указываются в разделе uses проекта или тех модулей, в которых они используются.

Главный файл проекта представляет собой текстовый файл, содержащий программный код, записанный на языке Object Pascal. Этот файл подключает все используемые программные модули и содержит операторы для запуска приложения. При создании нового приложения Delphi автоматически создаѐт файл проекта. Код файла проекта, содержащего одну форму, приведѐн ниже.

program Project1;

uses

Forms,

Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin

Application.Initialize;

Application.CreateForm(TForm1, Form1);

Application.Run;

end.

В разделе uses подключается системый модуль Forms и модуль формы Unit1.

Название формы приводится в фигурных скобках. Директива компилятора {$R *.res}

подключает к результирующему exe-файлу ресурсы.

Тело программы содержит операторы, которые готовят приложение к работе

(инициализируют), создают форму и начинают выполнение приложения. По мере создания новых форм содержимое этого файла меняется автоматически. Вручную этот файл корректируется только в особых случаях.

Чтобы увидеть код файла проекта, надо выполнить команду View|Unit через меню или с помощью кнопки на панели инструментов, а затем в диалоговом окне выбрать

Project1. Окно ViewUnit используется для вывода на экран кода файла проекта и входящих в него модулей.

При создании приложения Delphi генерирует пустую форму, текст модуля которой приведѐн ниже.

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;

type

18

TForm1 = class(TForm)

private

{ Private declarations }

public

{ Public declarations } end;

var

Form1: TForm1;

implementation

{$R *.dfm} end.

Модуль начинатся с зарезервированного слова unit, после которого пишется имя модуля. Имя модуля совпадает с именем файла, в котором он сохранѐн.

В интерфейсной секции описываются программные элементы (типы, переменные,

константы, процедуры, функции), которые могут быть использованы другими модулями программы. Всѐ, что помещается в секцию реализации implementation, доступно только в пределах модуля. Помимо объявлений, в эту секцию включают реализацию всех упомянутых в интерфейсной части процедур и функций, а также код любых дополнительных процедур и функций. В общем случае структура модуля имеет вид:

заголовок;

секция интерфейсных объявлений interface;

секция реализации implementation;

секция инициализации initialization;

секция завершения finalization;

терминатор end.

В необязательную секцию инициализации помещают операторы, которые осуществляют начальную настройку модуля и выполняются один раз при первом обращении к модулю. Необязательная секция finalization содержит операторы,

выполняемые только один раз при любом завершении программы: нормальном или аварийном. Раздел finalization вводится в программу только при наличии секции initialization.

3.1.2.Управление проектом

При старте Delphi автоматически создаѐт новый проект. При загрузке другого проекта (нового или имеющегося на диске) открытый ранее проект закрывается. Для создания нового проекта надо выполнить команду File|New|Application, а для загрузки

19

существующего – File|Open Project. Рекомендуется, создав новый проект, сразу сохранить его в отдельной папке и в дальнейшем регулярно выполнять сохранение всех файлов проекта.

Менеджер проекта Project Manager предназначен для управления проектами и составными частями разрабатываемого приложения. Его можно вызвать командой

View|Project Manager. Менеджер проектов позволяет работать с группой проектов: можно просматривать, добавлять и удалять проекты и их составные части. Если необходимо одновременно работать с несколькими проектами, то их целесообразно объединить в группу.

Окно менеджера проектов разделено на две части. В верхней части расположены управляющие элементы (раскрывающийся список и кнопки), а в нижней – перечень проектов и модулей с указанием путей к ним. При добавлении и удалении проектов и их составных частей автоматически вносятся изменения в соответствующие файлы.

В группе только один проект является активным. Активизировать проект можно выбрав его в раскрывающемся списке или с помощью кнопки Activate.

Некоторые из предусмотренных в менеджере проектов операции можно выполнить другим способом. Так, команда Project|Add to Project добавляет к проекту новую форму, а

команда Project|Remove from Project позволяет удалить существующую форму.

Обозреватель проекта Project Browser позволяет перемещаться по иерархии классов,

глобальных элементов и модулей проекта. Окно Обозревателя Exploring открывается командой View|Browser. Оно разделено на две части: Inspector pane (Панель просмотра) и

Details pane (Детальная панель). Кнопками можно задать один из трѐх доступных для просмотра объектов: глобальные элементы Globals, классы Classes или модули Units.

Получить доступ к параметрам обозревателя проекта можно также через окно Environment Options (Параметры среды), в котором параметры обозревателя проекта находятся на вкладке Explorer.

Репозиторий

Delphi позволяет многократно использовать одни и те же объекты в качестве шаблонов при дальнейшей разработке приложений. Для хранения таких объектов используется специальное хранилище Repository. При разработке приложения можно добавить в него объект из репозитория через окно New Items, которое вызывается командой File|New|Other. Большое количество объектов, находящихся в хранилище,

распределено по нескольким страницам: New (базовые элементы), Forms (формы), Projects

(проекты), Dialogs (диалоги), Data Modules (модули данных) и др. Кроме того,

пользователь может помещать в репозиторий свои заготовки.

20

Для добавления объекта к проекту необходимо выбрать страницу и указать объект.

Объекты можно добавлять к проекту различными способами, в зависимости от состояния переключателя в нижней части окна:

Copy – копирование объекта. Изменения, внесѐнные в проекте в копию объекта, не влияют на оригинал;

Inherit – от объекта в хранилище порождается новый объект, который добавляется к проекту;

Use – использование объекта из хранилища. Изменение этого объекта в проекте приводит к изменению объекта в хранилище и во всех проектах, использующих этот объект аналогичным образом (как Use).

Для помещения формы в репозиторий, следует сохранить еѐ в папке ObjRepos. Затем выполнить команду Add to Repository через контекстное меню. Если использовать команду Project|Add to Repository, то в репозиторий будет добавлен проект, а не форма.

Проекты из репозитория копируются целиком, с родительскими классами, что замедляет работу и увеличивает объѐм памяти. В диалоговом окне Add to Repository надо записать сведения о помещаемой в архив форме: название, пояснения, имя автора разработки,

название страницы хранилища.

3.1.3. Настройка параметров проекта

Установить параметры проекта можно двумя способами:

в окне Project Options,

программно.

Проще всего воспользоваться окном задания параметров объекта, которое открывается командой Project|Options. На странице Forms можно назначить главную форму приложения и в списке Auto-create forms выбрать формы, которые будут создаваться одновременно с главной. Главная форма открывается первой, и еѐ закрытие приводит к закрытию всего приложения.

На странице Application задают название и иконку, которые будут отображаться в среде Windows на панели задач, а также файл справки, подключаемый к проекту. На страницах Compiler и Linker устанавливают директивы компилятора и компоновщика

(редактора связей).

Заданные параметры Delphi автоматически заносит в соответствующие файлы проекта.

Программное задание параметров (использованием свойств объекта Application или включением в код директив компилятора и компоновщика) обладает приоритетом.