Структура проекта 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.
|