Цель работы:
– освоить описание типа класс и основные разделы текста модуля на конкретных примерах;
– усвоить порядок размещения и местоположения фрагментов текста модуля, записываемых совместно программистом и системой Delphi;
– овладеть техникой подготовки и размещения заготовок процедур – обработчиков событий и их программированием.
2. Основные сведения
2.1. Понятие класс, описание класса
Объекты окружающего нас физического мира обладают 3-мя характеристиками: они имеют набор свойств, способны разными методами изменять эти свойства и реагировать на события, возникающие как в окружающем мире, так и внутри самого объекта. В таком виде в языке Object Pascal реализовано понятие объекта, как совокупности свойств (структур данных, характерных для этого объекта), методов их обработки (подпрограмм изменения свойств) и событий, на которые данный объект может реагировать и которые часто приводят к изменению свойств объекта. Объекты могут иметь одинаковую структуру и отличаться только значениями свойств. Поэтому в Object Pascal введено понятие класс, а каждый конкретный объект, имеющий структуру этого класса, называется экземпляром класса.
Классом называют специальный тип, который содержит поля, методы и свойства.
Object Pascal характеризуется разветвленной структурой типов данных. Тип определяет: множество допустимых значений, которые может иметь класс (или объект), множество допустимых операций, которые применимы к нему, а также формат внутреннего представления данных в памяти компьютера.
Поля класса служат для хранения информации о классе и представляют собой данные, содержащиеся в классе.
Методами называются процедуры и функции, предназначенные для обработки полей. Описание метода похоже на описание обычной процедуры и часто называется процедурой-обработчиком события или просто процедурой. Заголовок метода (процедуры) располагается системой Delphi в описании класса. Сама процедура, реализующая метод, располагается программистом и системой Delphi в разделе реализации модуля (в разделе implementation). Имя метода (процедуры) в разделе реализации модуля является составным и включает в себя тип класса.
Свойства занимают промежуточное положение между полями и методами. С одной стороны, свойства можно использовать как поля, например, присваивать им значения, с другой стороны, внутри класса доступ к значениям свойств выполняют методы класса. Каждому свойству соответствует поле, содержащее значение свойств, и два стандартных метода read и write, обеспечивающих чтение значения поля, связанного со свойством, или запись нового значения в это поле.
В представлении программиста класс – это функционально законченный фрагмент программы, служащий образцом для создания подобных себе экземпляров. Используя сотни стандартных классов, созданных программистами корпорации Borland, или создав свой класс, программист может включать его экземпляры в разные программы или в разные места одной и той же программы.
Каждый компонент системы Delphi принадлежит к строго определенному классу, а все конкретные экземпляры компонентов, вставляемых в форму, получают имя класса с добавленным числовым индексом. По используемому в Delphi соглашению все имена классов начинаются с буквы T (это первая буква слова Type (пер. Тип)). Например, имя TForm1 означает имя класса, созданного по образцу стандартного класса TForm. Стандартный класс TForm реализует все нужное для создания и функционирования пустого Windows – окна.
Описание класса Form1, которое осуществляет Delphi, зависит от числа компонентов, расположенных в окне формы Form1 и числа методов. Например, если в окне формы Form1 разместить два компонента ComboBox1, ComboBox2, два компонента Label1, Label2 , две командные кнопки Button1, Button2 и три заготовки процедур, обрабатывающих события OnClick (пер. На щелчок), кнопок Button1, Button2 и события OnCreate (пер. При создании) формы Form1, то Delphi впишет в модуль следующее описание класса:
type
TForm1 = class(TForm) // Начало описания класса
Label1:TLabel;
Label2:TLabel;
ComboBox1: TComboBox;
ComboBox2: TComboBox;
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; // Конец описания класса
Это описание располагается системой Delphi в секции описания типов интерфейсного раздела модуля (после слова type). В нем ограничителями комментариев являются: символ // и фигурные скобки {}.
В первой строке этого описания за ключевым словом class (пер. Класс) в скобках указывается имя класса предка TForm. Это означает, что класс TForm1 является потомком класса TForm. Говорят, класс TForm1порожден (т.е. создан по образу) от класса-предка TForm и унаследовал все его возможности (поля, методы, свойства). Следующие строки указывают, что компоненты ComboBox1, ComboBox2 являются экземплярами стандартного класса TComboBox, компоненты Label1 и Label2 являются экземплярами стандартного класса TLabel, а компоненты Button1, Button2 является экземплярами класса TButton.
Строки procedure Button1Click(Sender:TObject); и procedure Button2Click(Sender:TObject); являются заголовками процедур-обработчиков событий OnClick командных кнопок Button1 и Button2. Строка procedure FormCreate(Sender: TObject); является заголовком процедуры-обработчика события OnCreate формы Form1.За именем процедуры в круглых скобках указано описание параметра вызова процедуры:
(Sender:TObject).
Параметр Sender (пер. Передающий тип) принадлежит базовому классу TObject. С его помощью подпрограмма, например Button1Click,определяет, какой компонент создал событие OnClick.
Описание класса TForm1 содержит два раздела: закрытый (private) и открытый (public). Эти разделы определяют области видимости элементов описания класса и обычно заполняются программистом при необходимости.
Областью видимости (локализации) элементов называется связь места их описания и места их использования.
Заканчивается описание класса двумя символами end;.
2.2. Создание заготовок процедур-обработчиков событий. Текст модуля программы
Для каждой формы, являющейся прообразом окна будущей программы, система Delphi создает отдельный модуль программы, в строго определенные места которого программист вписывает (вводит с клавиатуры) описания (объявления) элементов и операторы языка Object Pascal, реализующие алгоритм решения поставленной задачи. Другими словами; текст модуля доступен как системе Delphi, так и программисту. Поэтому программисту необходимо внимательно и точно работать в окнах формы (Form1) и редактора текста программы (Unit1.pas). Совместное с Delphi владение текстом модуля будет вполне успешным, если программист будет соблюдать простое правило: он не должен удалять или изменять строки, которые вставлены не им, а системой Delphi.
Содержимое двух разделов модуля (интерфейсного и реализации) система Delphi изменяет в зависимости от числа размещенных на форме компонентов программистом и последующих его действий. После оформления окна программы, наиболее ответственными моментами для программиста являются создание заготовок процедур-обработчиков событий (заготовок методов) и их программирование.
Создать заготовки процедур-обработчиков событий можно двумя способами. При первом способе:
– выбирается компонент (ЩЛК на нём);
– в окне Object Inspector открывается страница Events (ЩЛК на вкладке Events);
– в левой колонке этой страницы находится строка с названием события (например, OnCreate (пер. При создании)), затем в правой колонке этой строки производится 2ЩЛК.
2-й способ гораздо проще: вначале выбирается компонент (ЩЛК на нём) и производится 2 ЩЛК на этом компоненте. Delphi создаёт заготовку процедуры-обработки наиболее характерного для этого компонента события.
Например, текст заготовки процедуры, обрабатывающей событие ‘При создании’ (OnCreate) формы, выглядит так:
procedure TForm1.FormCreate(Sender: TObject); // Заголовок процедуры
begin // Начало тела процедуры
end; // Конец описания процедуры
После подготовки процедуры-заготовки, Delphi автоматически вносит её заголовок в описание класса TForm1. Составное имя процедуры TForm1.FormCreate содержит имя компонента Form1 и имя события Create. Это имя следует читать (в переводе с английского языка) справа налево: при создание формы компонента TForm1.
Перед созданием очередной заготовки процедуры, необходимо в окне Редактора текста программы переместить курсор в начало пустой строки, следующей после end; (конец описания предыдущей процедуры).
Операторы языка Object Pascal, реализующие алгоритм решения задачи, вводятся в полученную заготовку программистом между открывающей операторной скобкой begin и закрывающей операторной скобкой end;, фиксирующей конец описания процедуры – обработчика события. Совокупность этих операторов иногда называют телом процедуры.
Типы всех программных элементов, используемых операторами программы, могут быть описаны:
– между заголовком и телом процедуры-обработчика события в секции описания переменных (после ключевого слова var), если элементы ‘видны’ (локализованы) только в процедуре;
– в секции var интерфейсного раздела модуля, если элементы ‘видны’ (локализованы) для всех процедур-обработчиков событий.
Порядок размещения и местоположения фрагментов текста модуля более наглядно иллюстрируются на примерах выполнения конкретных заданий.
Задание 1. Составить программу (приложение), обеспечивающую:
– выбор пользователем фамилии студента из предварительно введенного 1-го списка;
– случайный выбор, из предварительно введенного 2-го списка, понятия, которое следует пояснить. Случайный выбор понятия должен производиться при ЩЛК на кнопке ‘Случайный выбор’;
– закрытие окна программы при ЩЛК на кнопке ‘Закрыть’.
1. Оформление окна программы
Для создания двух списков используем два компонента ComboBox1 и ComboBox2. Над этими компонентами нанесем надписи ‘Фамилия: ’ и ‘Поясните понятие: ’. Для этого используем два компонента Label1 и Label2. Для случайного выбора понятия и закрытия окна программы используем две командные кнопки Button1 и Button2. Разместив каждую пару одноименных компонентов рядом по горизонтали и соблюдая симметрию относительно вертикальной оси по центру формы, получим окно, представленное на рис. 1.
2. Изменение свойств компонентов.
Свойству Caption компонента Form1 зададим значение ‘Задание 1’. Свойствам Caption компонентов Label1, Label2 зададим значения ‘Фамилия:’, ‘Поясните понятие: ’ соответственно. Свойству Items (пер. Пункты) компонента ComboBox1 (после ЩЛК на кнопке с тремя точками), в окне String List Editor (Редактор списка строк) зададим пункты 1-го списка фамилий: Иванов, Петров, Сидоров, Волков, Зайцев, Медведев, Галкин, Соколов, Сорокин, Воробьев. Аналогично свойству Items компонента ComboBox2 зададим пункты 2-го списка понятий, которые следует пояснить: Класс, Тип (в языке Object Pascal), Поле, Свойства, Метод, Модуль, Информация, Процессор, Объект, Файл. Свойствам Caption компонентов Button1, Button2 зададим значения ‘Случайный выбор’ и ‘Закрыть’.
3. Получение заготовок процедур-обработчиков событий и их
программирование.
Создадим 3 заготовки процедур-обработчиков событий:
- procedure TForm1.FormCreate(Sender: TObject);
- procedure TForm1.Button1Click(Sender: TObject);
- procedure TForm1.Button2Click(Sender: TObject);
первым способом.
Введем в полученные заготовки процедур операторы, реализующие алгоритм задания 1.
3.1. Для того чтобы после запуска программы в полях ComboBox1 и ComboBox2 появлялись первые из списка фамилия студента и название понятия, в тело процедуры
procedure TForm1.FormCreate (Sender: TObject)
введем 2 оператора присваивания:
ComboBox1.Item Index:=0;
ComboBox2.Item Index:=0;
и вызовем стандартную процедуру Randomize (Располагать в случайном порядке), оператором:
Randomize;
Процедура Randomize в зависимости от момента времени запуска программы всегда выдает псевдослучайное число, которое используется для вычисления псевдослучайного числа функцией Random (N).
3.2. Для того чтобы при ЩЛК на кнопке ‘Случайный выбор’ в поле ComboBox2 появлялось случайно выбранное из списка название понятия, в тело процедуры:
procedure TForm1.Button1Click(Sender: TObject),
введем оператор присваивания:
ComboBox2.ItemIndex:=Random(ComboBox2.Items.Count);
В этом операторе функция Random(ComboBox1.Items.Count) вычисляет псевдослучайное число, равномерно распределенное на отрезке [0,N]. Верхняя граница N отрезка задается числом пунктов в списке, т.е. значением подсвойства Count (пер. Число пунктов) свойства Items (пер.Пункты) компонента ComboBox1. В этом задании N = 9, т.к. нумерация пунктов списка начинается с нуля.
3.3. Чтобы при ЩЛК на кнопке ‘Закрыть’, окно проекта закрывалось и выполнение программы прекращалась, в тело процедуры
procedure TForm1.Button2Click(Sender: TObject);
введем оператор вызова стандартной процедуры Close (Закрыть):
Close ;
После выполнения приведенных пунктов, текст модуля принимает следующий вид:
unit Unit1;//Заголовок модуля
interface// Начало интерфейсного раздела
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)//Начало описания класса
Label1: TLabel;
Label2: TLabel;
ComboBox1: TComboBox;
ComboBox2: TComboBox;
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;//Конец описания класса
var
Form1: TForm1;
implementation//Начало раздела реализации
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); // Заголовок 1-й процедуры
begin
Randomize;
ComboBox1.ItemIndex:=0;
ComboBox2.ItemIndex:=0;
end; // Конец описания 1-й процедуры
procedure TForm1.Button1Click(Sender: TObject); // Заголовок 2-й процедуры
begin
ComboBox2.ItemIndex:=Random(ComboBox2.Items.Count);
end; // Конец описания 2-й процедуры
procedure TForm1.Button2Click(Sender: TObject); // Заголовок 3-й процедуры
begin
Close;
end; // Конец описания 3-й процедуры
end.//Терминатор
В приведенном тексте модуля, который размещен в окне Unit1.pas, системой Delphi осуществляются нижеприведенные действия.
1. Записывается заголовок модуля unit Unit1. Он состоит из ключевого слова unit (пер. Модуль) и следующего за ним имени модуля Unit1, которое совпадает с именем дискового файла. В этот файл помещается исходный текст модуля, т.е. текст модуля хранится в дисковом файле Unit1.pas. Имя модуля служит для его связи с другими модулями и основной программой.
2. Определяется начало интерфейсного раздела модуля ключевым словом interface (пер. Интерфейс). В этом разделе системой Delphi:
а) записью специального предложения uses (пер. Использует) устанавливается связь модуля с другими модулями и основной программой:
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
В этом предложении после ключевого слова uses через запятую перечисляются имена модулей, с которыми устанавливается связь;
б) вводится секция описания типов type (пер. Тип), в которой описывается класс TForm1(см. стр. 3);
в) вводится секция описания переменных var (пер. Variables – Переменные), в которой описывается объект Form1 предложением
Form1:TForm1;
Объект Form1 формально относится к элементам программы, которые называются переменными.
3. Определяется начало раздела реализации модуля ключевым словом implementation (пер. Реализация). В этом разделе Delphi:
а) вписывает строку
{$R*.dfm},
которая является указанием (директивой) компилятору на необходимость подключения файла пользовательского интерфейса. Её запрещается удалять программистом;
б) размещает заготовки процедур- обработчиков событий, в которые программист вводит операторы, реализующие алгоритмы решения задачи, (записанные на языке Object Pascal).
4. Определяется конец текста модуля сочетанием ключевого слова end и символом ‘.’ (end.), которое иногда называется терминатором. Как только в тексте модуля встречается терминатор, компилятор прекращает анализ программы и игнорирует её оставшуюся часть.
Для выполнения задания 1, программистом вводятся в заготовки процедур только пять операторов.
Обычно в текстах модулей ключевые слова языка Object Pascal выделяются жирным шрифтом, а комментарии, поясняющие различные места программы и ничего не значащие для компилятора, записываются после // курсивом. Следует помнить, что ключевые слова не только приближают текст модуля к тексту на естественном английском языке, но каждое ключевое слово несет в себе условное сообщение для компилятора, который анализирует текст модуля слева направо и сверху вниз, как читаем его и мы.
Задание 2. Освоить основные свойства компонента Chart. Составить программу (приложение), которая строит график ‘затухающего’ синусоидального колебания:
где =0 c.– начальная граница отрезка;
=125 с – конечная граница отрезка;
t – текущее время;
e =2.7183 – основание натуральных логарифмов. В языке Object Pascal вычисление реализуется стандартной функцией exp(-k*t);
k=0.04 – коэффициент ‘затухания’ синусоидального колебания;
ω=2π*f=0.5 рад./с. – круговая частота синусоидального колебания;
f=0,08 Гц – частота;
T=1/f=12.5 c. – период колебания.
Компонент Chart (пер. Диаграмма)
Предназначен для построения диаграмм и графиков по наборам числовых данных. Chart находится на панели Additional (пер. Дополнительная) палитры компонентов, содержит большое число специфичных свойств, событий и методов. В частности, компонент Chart содержит объекты серий Series1, Series2,…, которые отображают наборы чисел в графическом виде и имеют тип TLineSeries. Иногда говорят, что Chart является контейнером объектов Series1, Series2,…. Стиль отображения данных (т.е. вид диаграммы) каждым объектом выбирается программистом в окне ‘TeeChart Gallery’(пер. Галерея диаграмм), которое открывается после ЩЛК на вкладке Series окна многостраничного Редактора диаграмм (Editing Chart).
Чтобы отобразить данные, нужно создать как минимум одну серию, например Series1. Реальный вид графика (диаграммы) зависит от фактических данных (в нашем случае от задаваемых значений t и вычисляемых значений, которые создаются в работающей программе и добавляются к серии с помощью метода AddXY (пер. Добавить по оси X и по оси Y) объекта Series1. Это реализуется оператором:
Series1.AddXY(t, y,’ ’,clRed);
В этом операторе: первым фактическим параметром, значения которого отображаются по оси 0X, является аргумент t; вторым фактическим параметром, значения которого отображаются по оси 0Y, является функция y; третий параметр является не обязательным; четвертый параметр (clRed) определяет цвет графика (Красный). Перед началом отображения графика следует очистить серию от занесенных в неё ранее данных, записав оператор:
Series1.Clear;
Без этого оператора повторное выполнение метода AddXY только добавит новые точки, не удалив прежние.
1. Оформление окна программы
Исходные данные этого задания определим в программе операторами присваивания. На форме Form1 разместим компонент Chart1 и командную кнопку Button1. При помощи маркеров Chart1 изменим его размеры так, чтобы он занимал большую часть Form1. Ниже Chart1 разместим Button1. Тогда эскиз окна программы примет вид, приведенный на рис. 5.2.
2. Изменение свойств компонентов
Свойствам Caption компонентов Form1 и Button1 зададим значения ‘Задание 2’ и ‘Построить график’ соответственно.
Двойным щелчком левой кнопки мыши (2ЩЛК) на компоненте Chart1 вызовем Редактор компонента ‘Editing Chart1’. В появившемся многостраничном окне автоматически откроется страница с вкладкой Series.
Создадим первую серию Series1, для этого:
– ЩЛК на кнопке Add;
– в открывшемся окне ‘TeeChart Gallery’ (пер. Галерея диаграмм) ЩЛК на рисунке Line выбираем вид графика;
– сбросим флажок перед полем 3D (устраняя представление графика в трехмерном пространстве) и ЩЛК на кнопке OK;
– зададим название графика. Для этого ЩЛК на вкладке ‘Titles’ и в появившемся поле вместо слова Chart введем заголовок ‘График функции’;
– ЩЛК на кнопке Close закроем окно ‘Editing Chart1’. В компоненте Chart 1 появится примерный вид графика (см. рис. 5.3).
3. Создание заготовки процедуры обработчика события и её программирование.
Создадим заготовку процедуры-обработчика события OnClick командной кнопки ‘График функции’ двойным щелчком левой кнопки мыши на ней.
В полученную заготовку введем описания переменных и операторы, реализующие вычисления функции и отображение её графика. Для этого:
1. Между заголовком процедуры и операторной скобкой begin введем секцию var, в которой опишем типы переменных:
var
t0,tk,w,t,h,y:real;
n,i:integer;
2. В тело процедуры запишем операторы, реализующие:
– присваивание переменным начальных значений, приведенных в задании;
– очистку серии Series1 от данных;
– в цикле: вычисление значений аргумента, функции и отображения их в Chart1.
Текст процедуры может выглядеть так:
procedure TForm1.Button1Click(Sender: TObject);//Заголовок процедуры
var//Секция описания переменных
t0,tk,w,t,h,y:real;
n,i:integer;
begin//Начало тела процедуры
w:=0.5;
tk:=125;
n:=80;
h:=tk/80;
t:=0.0;
Series1.Clear;
for i:=0 to 80 do//Заголовок оператора цикла
begin
y:=exp(-0.04*t)*sin(w*t);
Series1.AddXY(t,y,’ ‘,clTeeColor);
t:=t+h;
end;
end;//Конец описания процедуры
По мере оформления окна, создания заготовки процедуры-обработчика события OnClick, ввода описания переменных и операторов, система Delphi также будет формировать модуль, окончательный текст которого может выглядеть так:
unit Unit1;//Заголовок модуля
interface// Начало интерфейсного раздела
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms, Dialogs, TeEngine, Series, ExtCtrls, TeeProcs, Chart, StdCtrls;
type
TForm1 = class(TForm) // Начало описания класса
Button1: TButton;
Chart1: TChart;
Series1: TLineSeries;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;//Конец описания класса
var
Form1: TForm1;
implementation//Начало раздела реализации
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);//Заголовок процедуры
var
t0,tk,w,t,h,y:real;
n,i:integer;
begin
w:=0.5;
tk:=125;
n:=80;
h:=tk/80;
t:=0.0;
Series1.Clear;
for i:=0 to 80 do
begin
y:=exp(-0.04*t)*sin(w*t);
Series1.AddXY(t,y,’ ‘,clTeeColor);
t:=t+h;
end;
end;//Конец описания процедуры
end.//Терминатор
Литература: 210100 – «Электроника и наноэлектроника» Часть I Составители И. Ф. Яровой, Н. И. Бабанова