труктура проекта Delphi
Автор: Павел
Программа Delphi-это несколько
связанных между собой файлов.
Главный файл проекта,
изначально называется PROJECT1.DPR. Если
необходимо переименовать название
проекта, нужно перезаписать этот
файл, выбрав в меню File команду
Save Project As: При задании имени следует
придерживаться правил задания
имен в Object Pascal. Имя не должно
содержать пробелов (используйте
в таком случае знак подчеркивания),
должно начинаться с буквы
(цифры допустимы, но со второй
позиции), не должно содержать
других символов, кроме букв и
цифр. Под каким именем вы сохраняете
проект, под таким именем и
будет создаваться исполняемый
EXE файл, который вы всегда сможете
самостоятельно переименовать.
Модуль программы, который
автоматически появляется в начале
работы Unit1. Файл называется UNIT1.PAS по
умолчанию, но его можно назвать
любым другим именем, вроде MAIN.PAS.
Это делается аналогично переименованию
названия проекта. Необходимо
выбрать в меню File команду Save As:
Сохраняется активный модуль
в редакторе кода. Файл главной
формы, который по умолчанию
называется UNIT1.DFM, используется для
сохранения информации о внешнем
виде формы (окна разрабатываемого
приложения). При переименовании
названия модуля автоматически
меняет свое название. Файл PROJECT1.RES
изначально содержит иконку для
проекта. Создается автоматически.
Имеет одноименное название с
названием проекта. Файл PROJECT1.DSK содержит
информацию о состоянии рабочего
пространства. Состояние окон во
время разработки приложения. Исполняемый
EXE файл, который создается в процессе
компиляции проекта. Разумеется,
если сохранить проект под
другим именем, то изменят название
и файлы с расширением RES и
DSK. После компиляции программы
получаются файлы с расширениями:DCU
- скомпилированные модули PAS для
последующей быстрой компиляции
некоторые файлы не перезаписываются
EXE - исполняемый файл
~PA, ~DP - backup файлы редактора.
Автоматически создаются и содержат
информацию, перед последним сохранением.
И так, любая программа
всегда состоит из уже знакомого
нам файла проекта(такой файл
имеет расширение .dpr) и одного
или нескольких модулей(файлы
с расширением .pas) Файл проекта
не предназначен для редактирования
пользователем и создаётся автоматически
самой системой программирования Delphi.
Для того, чтобы увидеть содержимое файла
проекта, необходимо выполнить команду
Project|View Source.Содержимое файла проекта может
быть,например,следующим:
program Project1;
uses
Forms, unit in 'Unit1.pas' {Form};
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Файл проекта(главный
модуль) начинается словом program,за
которым следует имя программы,совпадающее
с именем проекта. Далее за
словом uses следуют имена используемых
модулей:стандартного модуля Forms и
модуля формы Unit1. Похожая на
комментарий директива {$R *.RES} указывает
компилятору,что нужно использовать
файл ресурсов,который содержит
описание ресурсов приложения,например,пиктограммы.Звездочка
указывает,что имя файла ресурсов
такое же,как и у файла проекта,но
с раширением .res. Исполняемая часть
главного модуля находится между
операторными скобками begin:end.Операторы
исполняемой части обеспечивают
инициализацию приложения и вывод
на экран стартового окна.Помимо
главного модуля каждая программа
включает как минимум один
модуль формы,который содержит
описание стартовой формы приложения
и поддерживающи* * *аботу процедур.В
Delphi каждой форме соответствует
свой модуль.Для переключения
между формой и окном редактора
кода,содержащего соответствующий
модуль,следует нажать на клавишу
F12.Модули-это программные единицы,служащие
для размещения фрагментов программ.При
помощи содержащихся в них
текстов программ и реализуется
решаемая пользователем задача.
Методы
Методами называются
инкапсулированные в классе процедуры
и функции. Например:
type
TChildClass = classFone: Integer;
Ftwo: string;
Fthree: Tobject;
function FirstFuns(x: real): real;
procedure SecondProc;
end
Для того чтобы обратиться
к методам,как и для полей,необходимо
использовать составные имена:
var
MyObject: TChildClass;
y: real;
begin
MyObject.SecondProc;
y := MyObject.FirstFunc(3.14);
end;
Методы,определенные в
классе,могут быть статическими,виртуальными,динамическими
или абстрактными.Тип метода определяется
механизмом перекрытия его в
потомках. Для статических методов
перекрытие осуществляется компилятором.
Например,пусть у нас имеется
описание родительского класса Tbase
и его потомка Tdescedant, содержащих
одноименный метод
MyJoy:
type
Tbase = class
procedure MyJoy;
end;
Tdescedant = class(Tbase)
procedure MyJoy;
end;
var
FirstObject: Tbase;
SecondObject: Tdescedant;
begin
FirstObject.MyJoy;
SecondObject.MyJoy;
end;
В соответствии с
принципом полиморфизма в операторе
FirstObject.MyJoy; вызывается метод, описанный
в классе Tbase,а в операторе SecondObject.MyJoy;
Вызывается метод,описанный в
классе Tdescedant.По умолчанию все
методы,описанные в классе,являются
статическими.Динамические и виртуальные
методы отличаются от статических
тем,что замещение родительских
методов методами потомков происходит
на этапе выполнения прогрммы.Для
обьявления виртуального метода
в родительском классе необходимо
использовать зарезервированное
слово virtual,а для обьявления
динамического метода-зарезервированное
слово dynamic.В классе-потомке в
загаловке замещающего метода
должно быть указано зарезервированное
слово override. Например:
type
TBase = class
Procedure MyJoy; virtual;
end;
Tdescedant = class(TBase)
procedure MyJoy; override;
end;
var
FirstObject: Tbase;
SecondObject: Tdescedant;
begin
FirstObject.MyJoy;
SecondObject.MyJoy;
end;
Если бы мы захотели,чтобы
метод MyJoy в классе Tbase был динамическим,
слово virtual в заголовке процедуры
следует заменить словом dynamic.Различие
между виртуальными и динамическими
методами невилико и связано
с особенностями реализации их
вызовов.Можно сказать,что виртуальные
методы более эффективны с точки зрения
затрат времени,а динамические методы
позволяют более рационально использовать
оперативную память.Абстрактными называются
виртуальный или динамические методы,которые
определены в классе,но не содержат никаких
действий,никогда не вызываются и обязательно
должны быть переопределены в классах-потомках.Обьявляется
абстрактный метод при помощи зарезервированного
слова abstract,расположенного после слов
virtual или dynamic,например:procedure MyMetod; virtual;
abstrat; Основное предназначение абстрактных
методов-быть родоначальником иерархий
конкретных методов в классах-потомках.
В любом классе содержатся два специальных
метода-конструктор и деструктор. Эти
методы содержатся в классе-родоначальнике
всех остальных классов-Tobject и,следовательно,наследуются
потомками. Как и другие методы,они могут
быть изменины в классах-потомках,т.е.перекрыты.
В классе Tobject и в большинстве его потомков
конструктор и деструктор называются
Create и Destroy соответственно. Конструкторы
предназначены для создания и инициализации
обьекта. Дело в том,что обьект в языке
Object Pascal является динамической структурой
и переменная-обьект содержит не сами
данныые, а ссылку на них. Конструктор
распределяет обьект в динамической памяти
и присваивает полям обьекта начальные
значения. При этом поля порядковых типов
в качестве начального значения получают
0, строкового-пустую строку, поля-указатели-значения
nil,поля-варианты-Unassigned. Кроме того,конструктор
помещает ссылку на созданный обьект в
переменную Self,которая автоматически
обьявляется в классе. Из сказанного следует,что
обращение к полям, свойствам и методам
обьекта должно осуществляться только
после вызова конструктора. Деструктор
освобождает динамическю память и разрушает
обьект. Для обьявления конструктора и
деструктора используются зарезервированные
слова constructor и destructor соответственно. Например:
type
Tsample = classText: string;
constructor Create;
destructor Destroy;
end;
Для того,чтобы создать
обьект,необходимо применить метод-конструктор
к классу обьекта: varMyObject : TSample;
begin
MyObject := TSample.Create;
end;
Если создается класс-потомок
и при его создании планируется
осуществить некоторые дополнительные
действия,отсутствующие у класса-родителя,
то в конструкторе класса-потомка
следует сначала вызвать конструктор
своего родителя, а уже потом
осуществлять дополнительные действия.
Вызвать любой перекрытый метод
родительского класса можно при
помощи зарезервированного слова inherited(унаследованный).
Например, если в классе TDescedant имеется
свой собственный конструктор typeTDescedant
= class(TBase)FMark : Boolean;
constructor Create(Mark: Boolean);
end;
то его реализация
могла бы быть такой: constructor TDescedant.Create(Mark:Boolean);
begin
inherited Create;
Emark := Mark;
end;
где вызов родительского
конструктора осуществляется оператором
inherited Create; а оператор Emark := Mark; Осуществляет
дополнительные действия. Кроме
деструктора Destroy,в базовом классе
Tobject определен метод Free, который
прежде проверяет, был ли обьект
на самом деле реализован и
только потом вызывает метод
Destroy. Если обьект не был создан
конструктором, то обращение к
деструктору,приведет к генерации
исключительной ситуации. Следовательно,для
уничтожения ненужного обьекта
удобнее использовать метод Free,
например: MyObject.Free; В классе могут
быть определены методы, которые
могут вызываться без создания
и инициализации обьекта. Эти
методы называются методами класса,и
для их обьявления используется
зарезервированное слово class. Например:
type
TChildClass = class(Tobject)
class function ChildClassInfo:
string;
end;
vary: string;
begin
y := ChildClassInfo;
end;
Как правило, методы
класса предназначены для справочной
информации о классе-имени класса,
предке класса, размере класса
и т.д.
События
Событие-это то,что
происходит в процессе работы
программы. В Delphi определенно
несколько десятков типовых событий.
Рассмотрим,что представляют собой
события с точки зрения языка
Object Pascal. Событие-это свойство процедурного
типа,и его значением является
указатель на некоторый метод.
Присвоить такому свойству значение
означает указать адрес метода,
который будет выполняться в
момент наступления события.Такие
методы называются обработчиками
событий. В качестве примера
рассмотрим,как описаны стандартные
события OnDblClick (возникает при
двойном щелчке левой кнопкой
мыши), OnMouseDown(возникает при нажатии
кнопки мыши) и OnMouseMove (возникает
при перемещении мыши) в классе
TControl:Tcontrol = class(Tcomponent) Private FonDblClick: TnotifyEvent;FonMouseDown:TmouseEvent;
FonMouseMove:TmouseMoveEvent protected property OnDblClick: Tnotify
read FonDblClick writeFonDblClick; Property OnMouseDown: TmouseEvent
read FonMouseDown writeProperty OnMouseMove: TmouseMoveEvent read FonMouseMove
writeFonMouseMove; end; Назначение зарезервированных
слов private и protected мы рассотрим
позже, а пока отметим следующее.
Поля FonDblClick,FonMouseDown и FonMouseMove, используемые
при описании свойств-событии,
предназначенны для хранения
указателя на метод, являющийся
обработчиком соответствующего
события. Используемые при описаний
полей процедурные типы определяются
следующим образом: TypeTnotifyEvent = procedure
(Sender: Tobject) of object; TmouseEvent = procedure(Sender:Tobject;Button:
TmouseButton; Shift: TshiftState; x, y: Integer) of object; TmouseMoveEvent
= procedure(Sender:Tobject; Shift: TshiftState;X, y:Integer) of object;
Общим для всех процедурных
типов является параметр Sender, содержащий
указатель на обьект-источник
события. Параметр Button содержит информацию,какая
клавиша мыши была нажата. Параметр
Shift содержит код клавиши,нажатой
на клавиатуре.x и y -текущие координаты
мыши в пределах компонента.
Поля
Полями называются
инкапсулированные в классе данные.
Поля класса подобны полям
записи, но в отличие от них
могут быть любого типа, в том
числе классами, например: type TchildClass
= class Fone : Integer; Ftwo : String; Fthree : TObject; end; Исходя
из принципа инкапсуляции,обращение
к полям должно осуществляется
при помощи методов и свойств
класса. Вместе с тем, в Object
Pascal допускается обращаться к
полям и непосредственно .Для
того чтобы обратиться к полю,
необходимо записать составные
имя, состоящее из имени класса
и имени поля,разделенных точкой,например:
var MyObject : TChildClass; begin MyObject.Fone := 16; MyObject.Ftwo
:= 'Некоторое строковое значение';
end; Обычно имя поля такое же,
как и имя соответствующего
свойства, но к имени поля в
качестве первой буквы добавляют
букву F.