
методические указания для выполнения лабораторных работ / Структура программ Lazarus
.docСтруктура программ Lazarus
Любая программа в Lazarus состоит из файла проекта (файл с расширением dpr) и одного или нескольких модулей (файлы с расширениями pas). Каждый из таких файлов описывает программную единицу Lazarus.
Структура проекта
Файл проекта представляет собой программу, написанную на языке Lazarus и предназначенную для обработки компилятором. Эта программа автоматически создается Lazarus и содержит лишь несколько строк. Чтобы увидеть их, запустите Lazarus и выберите команду Проект ► Просмотр исходника главного меню. Lazarus покажет окно кода с вкладкой Projectl, содержащее такой текст:
program Project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms
{ add your units here }, Unit1;
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
В окне кода полужирным шрифтом выделяются так называемые зарезервированные слова, синим шрифтом комментарии, а красным шрифтом директивы компилятора. Как видим, текст программы начинается зарезервированным словом program и заканчивается словом end с точкой за ним. Сочетание слова end со следующей за ним точкой называется терминатором программной единицы: как только в тексте программы встретится такой терминатор, компилятор прекращает анализ программы и игнорирует оставшуюся часть текста.
Зарезервированные слова играют важную роль в Lazarus, придавая программе в целом свойство текста, написанного на почти естественном английском языке. Каждое зарезервированное слово (а их в Lazarus несколько десятков) несет в себе условное сообщение для компилятора, который анализирует текст программы так же, как читаем его и мы: слева направо и сверху вниз.
Комментарии, наоборот, ничего не значат для компилятора, и он их игнорирует. Комментарии важны для программиста, который с их помощью поясняет те или иные места программы. В Lazarus комментарием считается любая последовательность символов, заключенная в фигурные скобки, в скобки со звездочками (*...*), а символы // указывают компилятору, что комментарий располагается за ними и продолжается до конца текущей строки.
Директива компилятора - компонент программы, управляющий последующей компиляцией программы. Директивы начинаются символом $, который стоит сразу за открывающей фигурной скобкой.
Например:
{$H-} Определяет, что строка будет обработан как ShortString
{$H+} Определяет, что строка будет обработан как AnsiString
Слово program со следующим за ним именем программы и точкой с запятой образуют заголовок программы. За заголовком следует раздел описаний, в котором программист (или Lazarus) описывает используемые в программе идентификаторы. Идентификаторы обозначают элементы программы, такие как типы, переменные, процедуры, функции. Здесь же с помощью предложения, которое начинается зарезервированным словом uses (использовать), программист сообщает компилятору о тех фрагментах программы (модулях), которые необходимо рассматривать как неотъемлемые составные части программы и которые располагаются в других файлах (например, Forms и Unit1).
Собственно тело программы начинается со слова begin (начать) и ограничивается терминатором end с точкой. Тело состоит из нескольких операторов языка Lazarus. В каждом операторе реализуется некоторое действие — изменение значения переменной, анализ результата вычисления, обращение к подпрограмме и т. п. В теле нашей программы — три исполняемых оператора:
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
Каждый из них реализует обращение к одному из методов объекта Application. Объектом называется специальным образом оформленный фрагмент программы, заключающий в себе данные и подпрограммы для их обработки. Данные называются полями объекта, а подпрограммы — его методами. Объект в целом предназначен для решения какой-либо конкретной задачи и воспринимается в программе как неделимое целое (иными словами, нельзя из объекта "выдернуть" отдельное поле или метод). Объекты играют чрезвычайно важную роль в современных языках программирования. Они придуманы для того, чтобы увеличить производительность труда программиста и одновременно повысить качество разрабатываемых им программ. Два главных свойства объекта — функциональность и неделимость — делают его самостоятельной или даже самодостаточной частью программы и позволяют легко переносить объект из одной программы в другую. Разработчики Lazarus придумали для нас с вами сотни объектов, которые можно рассматривать как кирпичики, из которых программист строит многоэтажное здание программы. Такой принцип построения программ называется объектно-ориентированным программированием (ООП).
В объекте Application собраны данные и подпрограммы, необходимые для нормального функционирования Windows-программы в целом. Lazarus автоматически создает объект-программу Application для каждого нового проекта. Строка
Application.Initialize;
означает обращение к методу initialize объекта Application. Прочитав эту строку, компилятор создаст код, который заставит процессор перейти к выполнению некоторого фрагмента программы, написанного для нас разработчиками Lazarus. После выполнения этого фрагмента (программисты говорят: после выхода из подпрограммы) управление процессором перейдет к следующей строке программы, в которой вызывается метод CreateForm и т. д.
Метод Application.Initialize вызывается "на всякий случай": в реальной программе он обычно ничего не делает. Его назначение — выполнить подпрограмму, имя которой размещается в системной переменной InitProc.
Метод CreateForm объекта Application создает и показывает на экране окно главной формы, а метод Run реализует бесконечный цикл получения и обработки поступающих от Windows сообщений о действиях пользователя. Когда пользователь щелкнет на кнопке Close, Windows передаст программе специальное сообщение, которое, в конечном счете, заставит программу прекратить работу и освободить назначенные ей системные ресурсы (память и процессор).
Следует сказать, что файл проекта полностью формируется самой Lazarus и в большинстве случаев не предназначен для редактирования. Именно по этой причине файл проекта имеет особое расширение и обычно не показывается в окне кода. При разработке сложных проектов этот файл можно использовать для выполнения некоторых специфических действий перед началом работы программы.
Структура модуля
Модули — это программные единицы, предназначенные для размещения отдельных частей программ. С помощью содержащегося в них программного кода реализуется вся поведенческая сторона программы.
Любой модуль имеет следующую структуру:
-
заголовок;
-
секция интерфейсных объявлений;
-
секция реализаций;
-
терминатор.
Заголовок открывается зарезервированным словом unit, за которым следует имя модуля и точка с запятой. Секция интерфейсных объявлений открывается зарезервированным словом interface, а секция реализаций — словом implementation (выполнение). Терминатором модуля, как и терминатором программы, является слово end с точкой. Следующий фрагмент программы является синтаксически правильным вариантом модуля:
unit Unitl;
interface // Секция интерфейсных объявлений
{ Здесь находятся описания процедур и функций модуля, которые могут использоваться другими модулями }
implementation // Секция реализаций
{ Здесь находятся описания (текст) процедур и функций модуля }
initialization // Код, выполняемый при запуске программы end.
В секции интерфейсных объявлений описываются программные элементы (типы, классы, процедуры и функции), которые могут использоваться другими модулями, а в секции реализаций раскрывается механизм работы этих элементов. Раздел инициализации initialization является не обязательным. Он необходим для выполнения кода при запуске программы.
Ниже приведен текст модуля простого примера.
unit Unit1;
interface // Открытый интерфейс модуля
{Список подключаемых модулей}
uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls;
{Объявление класса формы}
type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure Button1Click (Sender: TObject);
private // Закрытый раздел класса
{ Private declarations }
{Сюда могут помещаться объявления переменных, функций и
процедур, включаемых в класс формы, но не доступных для
других модулей}
public // Открытый раздел класса
{ Public declarations }
{Сюда могут помещаться объявления переменных, функций и
процедур, включаемых в класс формы и доступных для
других модулей}
end;
var
Form1: TForm1;
{Сюда могут помещаться объявления типов, констант,
переменных, функций и процедур, к которым будет доступ
из других модулей, но которые не включаются в класс
формы}
implementation // Реализация модуля
{$R *.DFM}
{Сюда могут помещаться предложения uses, объявления типов,
констант, переменных, к которым не будет доступа из
других модулей. Тут же должны быть реализации всех
объявленных в разделе interface функций и процедур,
а также могут быть реализации любых дополнительных, не
объявленных ранее функций и процедур.}
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := 'Это мое приложение!';
end;
end.
Lazarus является объектно-ориентированным языком программирования. В основе объектной модели Паскаля лежат понятия класса и объекта. Класс — это сложная структура, включающая, помимо описания данных, описание процедур и функций, которые могут быть выполнены над представителем класса — объектом.
В разделе interface после предложения uses, содержащего список подключаемых библиотечных модулей, можно увидеть объявление класса формы, подготовленное Lazarus. Имя класса формы — TForm1. В класс включены те объекты, которые размещены на форме — метка Label1 и кнопка Button1. Кроме того в класс включено объявление обработчика щелчка на кнопке — процедура Button1Click.
Стандартный класс TForm реализует все нужное дли создания и функционирования пустого Windows-окна. Класс TForm1 порожден от этого класса, о чем свидетельствует строка
TForm1 = class(TForm)
в которой за зарезервированным словом class в скобках указывается имя родительского класса. Термин "порожден" означает, что класс TForm1 унаследовал все возможности родительского класса TForm и добавил к ним собственные в виде дополнительных компонентов. Перечень вставленных нами компонентов и составляет значительную часть описания класса.
В классе предусмотрено также два раздела: private — закрытый раздел класса, и public — открытый раздел класса. То, что вы или Lazarus объявите в разделе public, будет доступно для других классов и модулей. То, что объявлено в разделе private, доступно только в пределах данного модуля.
После завершения объявления класса формы вы можете видеть строки
var
Form1: TForm1
Это объявляется переменная Form1 класса TForm1, т.е. объявляется форма как объект класса TForm1.
Программный доступ к свойствам и методам объектов
Рассмотрим теперь, как получить из программы доступ к свойствам и методам объектов. Если вас интересует какое-то свойство объекта, то ссылка на него осуществляется в следующем формате:
<имя объекта>.<имя свойства>
После имени объекта пишется без пробела символ точки, а затем так же без пробела пишется имя свойства. Например, ссылка на свойство Caption метки Label1 осуществляется записью Label1.Caption (см. в тексте примера предыдущего раздела процедуру TForm1.Button1Click).
Иногда свойство объекта является в свою очередь объектом. Тогда в обращении к этому свойству указывается через точки вся цепочка предшествующих объектов. Например, метки имеют свойство Font — шрифт, которое в свою очередь является объектом. У этого объекта имеется множество свойств, в частности, свойство Color — цвет шрифта. Чтобы сослаться на цвет шрифта метки Label1, надо написать Label1.Font.Color. Это означает: свойство Color объекта Font, принадлежащего объекту Label1. Например, оператор
Label1.Font.Color:=clRed;
сделает надпись метки Label1 красной.
Аналогичная нотация с точкой используется и для доступа к методам объекта. Например, для метки, как и для большинства других объектов, определен метод Free, который уничтожает метку и освобождает занимаемую ею память. Если вы в какой-то момент решили уничтожить метку Label1 в своем приложении, то вы можете написать оператор
Label1.Free;
Теперь посмотрим, чем различаются константы, переменные, функции и процедуры, включенные и не включенные в описание класса.
Если в приложении создается только один объект данного класса (в нашем примере — только один объект формы класса TForm1), то различие в основном чисто внешнее. Для процедур, объявленных в классе, в их описании в разделе implementation к имени процедуры должна добавляться ссылка на класс. В нашем примере имя процедуры Button1Click в описании этой процедуры в разделе implementation заменяется на TForm1.Button1Click. Для процедур, объявленных вне класса, такой замены не требуется.
Обращение к переменным и процедурам, описанным внутри и вне класса, из процедур, описанных вне класса, различается. К переменным и процедурам, описанным вне класса, обращение происходит просто по их именам, а к переменным и процедурам, описанным в классе, через имя объекта класса. Например, если вы вне класса хотите описать какую-то процедуру, изменяющую надпись метки Label1, вы должны обратиться к ее свойству Caption следующим образом: Form1.Label1.Caption. Только через ссылку на объект Form1 внешние по отношению к классу процедуры могут получить доступ ко всему, объявленному в классе.
Все эти ссылки на объект не требуются в процедурах, объявленных в классе. Поэтому в процедуре TForm1.Button1Click ссылка на объект Label1 не содержит дополнительной ссылки на объект формы.
В объектно-ориентированных языках есть 3 основных понятии: инкапсуляция, наследование и полиморфизм.
Инкапсуляцией называется объединение в классе данных и подпрограмм для их обработки. Инкапсуляция позволяет создавать класс, как нечто целостное, имеющее определённую функциональность.
Наследование – это когда любой класс может быть порождён другим классом. Порождённый класс автоматически наследует все поля, методы, свойства и события.
Полиморфизм позволяет использовать одинаковые имена для методов, входящих в различные классы.