Лабораторная работа № 2 - Группа П

advertisement
1
Лабораторная работа № 1
Программирование на языке Object Pascal
1. Введение
Целью настоящей лабораторной работы является знакомство с
основными особенностями и возможностями языка программирования
Object Pascal, который занимает центральное место в системе
программирования DELPHI.
Язык Object Pascal является дальнейшим развитием языка
Turbo/Borland Pascal, но, при сохранении многих общих элементов, имеет
ряд отличительных особенностей. Они определяются, главным образом,
работой пакета DELPHI в операционной системе Windows и
потребностями визуального программирования.
В лабораторной работе относительно подробно рассматриваются
основные элементы, актуальные для Object Pascal (за исключением
элементов
объектно-ориентированного
программирования,
чему
посвящена отдельная лабораторная работа), и опускаются все те, которые
присутствуют в обычном Паскале. Рассмотрение сопровождается
примерами простых программ, которые составляют практическую часть
работы и должны выполняться в ходе лабораторной работы. Невысокая
сложность, а в ряде случаев даже примитивность примеров объясняются
тем, что они служат лишь для целей иллюстрации тех или иных
особенностей языка. Все примеры практической части должны
выполняться в среде DELPHI. Их содержание в описании лабораторной
работы выделены курсивом.
2. Алфавит языка Object Pascal
Алфавит языка (набор символов) Object Pascal является
подмножеством набора символов кода ASCII и по сравнению с
алфавитом обычного Паскаля имеет следующие особенности:
 введен еще один вид комментария, признаком которого служит
двойная косая черта //. Все символы после этого признака до конца
строки являются комментарием;
 добавлены следующие новые зарезервированные слова: as, class,
except, finalization, finally, initialization, is, on, property, raise,
threadvar, try. Их смысл и назначение раскрываются в дальнейшем
при рассмотрении соответствующих конструкций языка;
 введены следующие новые директивы: abstract, automated, cdecl,
default, dispid, dynamic, message, nodefault, override, pascal, protected,
published, read, register, stdcall, stored, write. Лексемы private,
protected, published и automated внутри описания классов действуют
2
как ключевые слова, а во всех остальных случаях – как стандартные
директивы.
3. Структура программы
Программа на языке Object Pascal имеет типичную структуру,
включающую:
1) заголовок;
2) раздел указания используемых модулей;
3) раздел описаний;
4) операторный раздел.
В разделе описаний введен новый подраздел, открывающийся
ключевым словом threadvar и предназначенный для описания поточнолокальных переменных, используемых для работы с потоками при
разработке многопоточных приложений.
4. Типы данных
В языке Object Pascal по сравнению с Turbo/Borland Pascal
пересмотрена концепция построения основных типов. Группы целых,
символьных и строковых типов подразделяются на две категории:
1. Фундаментальные (fundamental) типы, формат представления
которых в памяти строго фиксируется и будет выдерживаться
неизменным во всех последующих реализациях Object Pascal для
любых операционных систем и компьютерных платформ.
2. Родовые (generic) типы, формат представления которых в памяти
не фиксируется и будет устанавливаться наиболее оптимальным
способом для конкретной операционной системы и компьютерной
платформы.
К фундаментальным типам относятся:
 целые типы Shortint, Smallint, Longint, Byte, Word;
 символьные типы AnsiChar и WideChar;
 строковые типы ShortString и AnsiString.
К родовым типам относятся:
 целые типы Integer и Cardinal;
 символьный тип Char;
 строковый тип String.
Для вещественных и булевских типов разделение на
фундаментальные и родовые типы отсутствует. В целом, как и ранее, все
типы
разделяются
на
стандартные
(предопределенные)
и
пользовательские.
В группу стандартных целых типов добавлены два новых типа:
Smallint и Cardinal. Их характеристики приведены в табл. 1.
3
Таблица 1. Целые типы Smallint и Cardinal
Имя типа
Диапазон
представления
Формат
Размер в байтах
Smallint
-32768 .. 32767
Знаковый
2
Cardinal
0 .. 2147483647
Беззнаковый
4
При написании программ рекомендуется отдавать предпочтение
типам Integer и Cardinal, так как их использование процессором более
эффективно.
В группу вещественных типов по сравнению с реализациями
Turbo/Borland Pascal добавлен тип Currency. Его характеристики
представлены в табл. 2.
Таблица 2. Вещественный тип Currency
Значащие
Диапазон
Размер
Название типа
цифры
представления
байт
мантиссы
Вещественный
повышенной
точности в
922337203685477.5808..
19 .. 20
8
формате с
922337203685477.5807
фиксированной
точкой
Тип Currency предназначен в основном для финансовых
вычислений, так как охватывает практически любой диапазон денежной
массы и позволяет учитывать двойную систему денежных единиц.
Object Pascal так же, как и Turbo/Borland Pascal, поддерживает
четыре булевских типа Boolean, ByteBool, WordBool и LongBool.
В Object Pascal расширена группа символьных типов: к
традиционному типу добавлены типы AnsiChar и WideChar (табл. 3).
Таблица 3. Символьные типы AnsiChar, WideChar
Имя типа
Размер в байтах
AnsiChar
1
WideChar
2
Кодировка
Unicode
4
Тип AnsiChar по своим характеристикам совпадает с типом Char.
Первые 256 символов кодировки Unicode в типе WideChar совпадают с
символами ANSI-кодировки, но сами типы AnsiChar и WideChar
непосредственно несовместимы.
Задание 1. Подготовить и выполнить программу вывода на
экран символов ANSI-кодировки, за исключением служебных символов с
кодами от 0 до 31.
Примечание. В программе использовать форму, содержащую
кнопки “Операция” и “Закрыть” Эту же форму использовать как
исходную во всех последующих заданиях, взяв в качестве ее заголовка
текст “Задание № “ с указанием текущего номера задания. Для вывода
символов использовать компоненту Memo стандартной страницы
палитры компонент.
В группу пользовательских типов введены два новых типа:
вариантный тип – Variant и тип указателей на классы, описания которых
вводятся ключевыми словами class of. Вариантные типы используются
для работы с переменными, тип которых на этапе компиляции
неизвестен, а также для динамического изменения типа этих переменных
во время выполнения. Подробнее о вариантных типах см. [1, п.4.3.7].
В ряде случаев требуется преобразовать переменную одного
типа в переменную другого типа. В Object Pascal имеется несколько
стандартных подпрограмм, выполняющих преобразование типов данных.
Основные сведения о них приведены в приложении 1.
Задание
2.
Подготовить
и
выполнить
программу
преобразования
шестнадцатеричного
числа
в
десятичное.
Шестнадцатеричное число задавать по правилам представления таких
чисел в языке, т.е. начиная с символа $. При вводе предусмотреть
проверку правильности преобразования.
Примечание. Ввод данных осуществить с помощью компоненты
Edit.
5. Выражения и операции
Язык Object Pascal полностью поддерживает все возможности
предыдущих версий Паскаля по обработке выражений и множеству
используемых для этого операций. Имеются два нововведения:
 операции as и is, позволяющие осуществить доступ к
информации о типах времени выполнения (RTTI – Run Time
Type Information) для классов и объектов;
 правила преобразования типов и выполнения операций при
вычислении выражений, в которых присутствуют операнды
нового типа Variant.
5
Операции as и is позволяют определять во время выполнения
принадлежность объектов к определенному классу или одному из его
потомков, а также осуществлять безопасное преобразование классовых
типов. Такие действия широко используются при работе с компонентами
DELPHI. Они рассматриваются в лабораторной работе № 3, посвященной
изучению основ объектно-ориентированного программирования в языке
Object Pascal.
Вариантные типы также предоставляют дополнительные
возможности на этапе выполнения, поскольку позволяют работать со
значениями, тип которых неизвестен во время компиляции.
Задание 3. В программе заданы 4 подряд идущих переменных
X,Y,Z,W, имеющих типы соответственно Byte, Word, Longint, Integer.
Подготовить и выполнить программу вывода адресов и размеров
памяти (в байтах) этих переменных в виде таблицы следующей формы:
Адрес
Размер
Byte
Word
Longint
Integer
.
Примечание. Для вычисления адресов можно воспользоваться
операцией @. Чтобы вывести значение адреса на экран, следует
преобразовать адрес в целое число, например типа Longint, с помощью
функции IntToStr.
Чтобы найти размеры областей памяти, отводимых под
переменные, следует сравнить адрес текущей переменной и адрес
следующей переменной. Для нахождения размера памяти последней
переменной нужно после нее записать какую-либо дополнительную
переменную.
Для создания таблицы в форме следует использовать
компоненту StingGird, которая расположена на странице Additional. С
помощью инспектора объектов удалить линейку скроллинга таблицы и
задать ее размеры с помощью свойств RowCount и ColCount.
Содержимое каждой ячейки таблицы задается свойством Cells.
При этом положение каждой ячейки определяется двумя индексами,
задающими номер столбца и строки. Нумерация столбцов и строк
начинается с нуля.
6
6. Операторы
По сравнению с версией Turbo/Borland Pascal в Object Pascal в
операторах языка сделаны следующие дополнения:
1. В семантике оператора case введены два изменения, которые
позволяют получить на этапе компиляции более
эффективный машинный код для этого оператора:
 диапазоны, задаваемые списками констант, не должны
пересекаться;
 списки констант в альтернативных ветвях оператора case
должны располагаться в возрастающем порядке.
Первое требование является обязательным, второе – нет. Однако
при его невыполнении сгенерированный компилятором код не будет
оптимальным.
2. Введен новый оператор try, который предназначен для
обработки исключительных ситуаций и имеет две
разновидности. Конструкция try…except служит для
обработки
конкретных
исключительных
ситуаций.
Конструкция try…finally обеспечивает выполнение группы
операторов
вне
зависимости
от
возникновения
исключительной ситуации.
Примечание. Обработке исключительных ситуаций посвящена
отдельная лабораторная работа.
Состав основных групп операторов языка и их функции не
претерпели изменений.
Задание 4. Подготовить и выполнить программу, выполняющую
ввод целого числа и вывод символа в ANSI-коде, соответствующего
этому числу. Если символа нет, то должно быть выведено сообщение
“Символа нет”. Управляющие символы не учитываются.
Примечание. Ввод числа и вывод результата выполнить с
помощью компонент типа Edit. Строку ввода исходного числа пометить
текстом “Число”, а строку вывода результата – текстом “Символ”.
Задание 5. Внести изменения в предыдущую программу, чтобы
она при вводе каждого очередного знака распознавала его тип и
выдавала следующие сообщения: “Цифра”, “Строчная буква”,
“Прописная буква”, “Управляющий символ”, “Другой символ”.
Задание 6. Подготовить и выполнить программу нахождения
всех положительных делителей целого числа (кроме единицы и самого
числа).
Примечание 1. Использовать следующий алгоритм: исходное
число делится на все целые числа, начиная с двух и кончая числом,
равным половине заданного числа. Если остаток при делении будет
равен нулю, то делитель найден.
7
Примечание 2. Для ввода исходного числа в форме использовать
строку ввода Edit, которую пометить текстом “Целое число”. Для
вывода делителей числа использовать компоненту ListBox (Список)
страницы Standard. 1 Выполнение программы начать нажатием кнопки
“Операция”. Для вывода элементов списка использовать свойство Items.
компоненты ListBox. С целью многократного использования программы
без перезагрузки перед началом поиска делителей очистить список с
помощью метода Clear свойства Items. При обнаружении очередного
делителя записывать в список его порядковый номер и значение с
помощью метода Add. Если делителей у числа нет, вывести сообщение
“Исходное число – простое”.
7. Структурированные типы данных
Структурированные типы данных определяют наборы
однотипных (однородных) или разнотипных (неоднородных) элементов,
типы которых образуются из других типов (простых, структурированных,
указателей и т. д.).
Структурированные типы Object Pascal включают в себя все
типы этого класса, существующие в версиях Turbo/Borland Pascal, к
которым добавлены следующие новые типы:
 две разновидности строкового типа ShortString и AnsiString;
 тип указатель на класс class of.
В настоящем пункте основное внимание уделено новым
строковым типам, а также некоторым другим, за исключением файлового
типа, который рассматривается в следующем разделе работы.
Тип class of, как и тип class, связан с объектно-ориентированной
методологией разработки программ, которой посвящена отдельная
лабораторная работа.
Строки типа ShortString (“короткая” строка) и AnsiString
(“длинная” строка) могут использоваться наряду с основным строковым
типом String и типом Pchar, описывающим строку, которая оканчивается
нулем. Универсальная строка типа String может использоваться и как
“короткая” строка, и как “длинная” строка в основном в зависимости от
директивы
компилятора
{$H}
или
параметра
Project|Options|Compiler|Huge strings главного меню. Если задана
директива {$H+} или установлен указанный параметр, строка типа String
ведет себя как “длинная”. В противном случае – как “короткая”. Строки
типа String с явно заданным размером всегда являются “короткими”.
1
Описание компоненты см. в [2, с. 278].
8
Строка типа ShortString представляет собой одномерный массив,
в который можно поместить до 255 символов. Однако, в отличие от
обычного массива, ShortString-строка имеет не фиксированную длину, а
две разновидности длины:
 общую длину строки, которая определяет размер памяти,
выделяемый короткой строке при ее описании;
 текущую длину (она всегда меньше или равна общей длине),
которая показывает количество смысловых символов короткой
строки в данный момент времени.
Текущая длина ShortString-строки указывается в нулевом (то есть
имеющем индекс 0) элементе строки. В него записывается символ, код
которого равняется значению текущей длины. Нулевой элемент строки
при этом сделан невидимым для программиста, однако использовать его
в программах допускается.
Строка ShortString совместима со строками любых других типов.
Ей можно присваивать значение другой строки или строкового
выражения. При этом другие типы строк приводятся к типу ShortString.
Значение строки ShortString также допускается присваивать строке
другого типа за исключением строки типа Pchar.
Строка типа AnsiString (строка для размещения символов ANSIкодировки) представляет собой массив, в который можно поместить
любое количество символов. В отличие от ShortString-строк память под
такие строки выделяется не статически, а динамически. “Длинные”
строки не имеют максимальной длины, устанавливаемой при объявлении,
а только динамическую текущую длину. Переменная, соответствующая
такой строке, фактически является указателем на динамически
выделенную под эту строку область памяти. Если строка является пустой,
этот указатель имеет значение nil2.
Строки типа AnsiString обладают такими же свойствами
совместимости со строками других типов, что и ShortString-строки.
В операциях со строками широко используются различные
стандартные подпрограммы, краткие описания которых приведены в
приложении 2.
Задание 7. Подготовить и выполнить программу определения
текущих характеристик строки типа ShortString.
2
Подробнее о Short- и Ansi-строках см [1, с. 60-65].
9
Примечание. Для решения задачи использовать программу
задания 6, внеся в нее некоторые изменения. В разделе объявления
переменных ввести строковую переменную Str типа ShortString и
инициализировать ее значением “Короткая строка”. Компоненту Edit
формы пометить текстом “Строка”. Ее следует использовать в
процессе работы программы для ввода новых строк.
В процедуре обработчика событий, инициируемой нажатием
кнопки “Операция”, разместить операторы, выполняющие следующие
действия:
1. Ввод новой строки.
2. Очистка списка.
3.Добавление в строки списка параметров текущей строки: общего и
текущего размеров строки, текста строки и ее первого символа.
Значение каждого параметра сопроводить текстом, поясняющим его
название.
Для получения общего размера строки использовать
стандартную функцию SizeOf, определяющую размер аргумента в
байтах, а для получения текущего размера – стандартную функцию
Length.
Добавить в создаваемый программный модуль процедуру
обработчика событий FormCreate, обрабатывающего событие
OnCreate, которое возникает при создании формы и по которому
начальное значение строки Str присваивается свойству Text строки
ввода Edit1.
Запустить
программу
на
выполнение
и
получить
характеристики исходной строки. Изменить информацию в строке
ввода, нажать кнопку “Операция” и проанализировать, как будут
изменяться параметры строки. Рассмотреть частный случай, когда
длина строки равна нулю.
Задание 8. Подготовить и выполнить программу определения
текущих характеристик “длинной” строки AnsiString.
Примечание. Для решения задачи использовать программу
задания 6, внеся в нее соответствующие изменения. Вместо переменной
Str типа ShortString ввести новую инициализированную переменную типа
AnsiString. Дополнительно для текущей строки определить еще один
параметр: код символа завершения строки, идущего за последним
помещенным в строку символом и имеющего номер, равный значению
выражения Length(Str)+1.
Аналогично заданию 6 получить характеристики нескольких
“длинных” строк.
По результатам выполнения заданий 7 и 8
сопоставить характеристики строк типа ShortString и AnsiString
между собой.
10
Задание 9. Подготовить и выполнить программу, которая
выполняет ввод строки символов, состоящей из строчных и заглавных
букв латинского алфавита, цифр и пробелов, и осуществляет проверку
правильности введенных символов. При обнаружении первого
неправильного символа должно быть выдано сообщение “Неправильная
строка”, символ выделен и дальнейший анализ прекращен. Если все
символы строки правильные, то должно быть выдано сообщение
“Правильная строка”.
Примечание. Ввод строки символов выполнить с помощью
компоненты Edit. Название кнопки “Операция” изменить на
“Проверка”. При проверке введенных символов совокупности правильных
символов представить с помощью конструктора множеств диапазонов
этих символов. При обнаружении неверного символа осуществить
активизацию строки ввода с помощью метода SetFocus и выделить
этот символ путем задания свойствам SelStart и SelLength3
соответствующих значений. Для вывода сообщений использовать
компоненту Label.
8. Организация ввода-вывода
В языке Object Pascal ввод-вывод информации осуществляется
тремя способами:
1. Ввод-вывод с использованием интерфейсных элементов типа
строк и окон ввода, меток, окон сообщений и т. д.
2. Традиционный ввод-вывод с использованием файлов и
файловых переменных.
3. Ввод-вывод основанный на применении дескрипторов
файлов.
В настоящей работе затрагиваются первые два способа как
получившие наибольшее распространение.
Простейшими средствами ввода данных являются компоненты
Edit (строка ввода) и Memo (редактор текста)4. В первом случае ввод
осуществляется с помощью свойства Text компоненты, во втором –
свойства Lines. В обоих случаях вводимые значения имеют строковый
тип. Поэтому если в результате ввода надо получить значение целого или
вещественного типа, то введенная строка должна быть преобразована в
число с помощью соответствующей функции преобразования.
Другой способ ввода основан на использовании так называемого
окна ввода, которое может быть создано с помощью двух подпрограммфункций: InputBox и InputQuery.
3
4
Описания этих свойств см. в [2, с. 276].
Описание компонент см. в [2, с.275, 276].
11
Подпрограмма InputBox(Caption, Prompt, Default) размещает на
экране диалоговое окно с заголовком Caption типа string для ввода строки
символов. Параметр Prompt типа string содержит пояснение, какую
информацию следует вводить, параметр Default (также типа string) –
текст, находящийся в строке ввода в момент появления окна ввода на
экране. Кроме строки ввода диалоговое окно содержит кнопки OK (Ввод)
и Cancel (Отмена), а также кнопку закрытия окна на его верхней строке.
Подпрограмма возвращает введенную строку, если окно закрыто кнопкой
OK, и исходную строку, если окно закрыто кнопкой Cancel.
Подпрограмма InputQuery(Caption, Prompt, Value) выполняет по
существу ту же самую функцию, но ее результат имеет логический тип.
Параметр Value представляет собой текст, набранный в строке ввода.
Возвращаемое значение имеет тип True, если окно закрыто кнопкой OK,
и False, если окно закрыто кнопкой Cancel.
Простейшим средством текстового вывода данных является
компонента Label (метка). Чтобы вывести текстовую строку на экран,
следует присвоить ее в качестве значения свойству Caption метки. Если
требуется вывести числовое значение, то предварительно его необходимо
преобразовать в строку символов с помощью функции IntToStr или
FloatToStr.
Удобным средством вывода является вывод с помощью окон
сообщений. В языке для этого имеется несколько функций и процедур,
позволяющих различным образом отображать информацию.
Функция MessageBox(Text, Caption, Flags), являющаяся методом
класса TApplication, позволяет вывести сообщение Text (типа Pchar) в
окно с заголовком Caption (также типа Pchar). Параметр Flags (типа
Longint) задает способ оформления окна с помощью различных
управляющих кнопок и значков. Описание значений этого параметра
приведено в [2, с.364].
Процедуры ShowMessage(Msg) и ShowMessagePos(Msg, X, Y)
предназначены для вывода на экран сообщения Msg (типа String) в виде
информационного окна. Отличие этих процедур состоит в том, что
первая выводит окно в центр экрана, а вторая – таким образом, что его
левый верхний угол имеет координаты X и Y.
Помимо сообщения Msg, окно имеет кнопку OK и кнопку
закрытия на заголовке. Заголовок окна совпадает с названием
приложения, из которого оно вызвано.
Подпрограммы-функции MessageDlg(Msg, Type, Buttons,) и
MessageDlgPos(Msg, Type, Buttons, Help, X, Y) выводят диалоговое окно с
сообщением Msg (типа String) и набором кнопок. Их отличие такое же,
что и процедуры ShowMessage и ShowMessagePos.
12
Параметр Type определяет вид выводимого окна и задается
следующими именованными константами:
 mtWarning – окно с предупреждением, содержит желтый
восклицательный знак;
 mtError – сообщение об ошибке, содержит белый крест в
красном круге;
 mtInformation – информационное сообщение, содержит
синий знак i;
 mtConfirmation – запрос подтверждения, содержит зеленый
знак вопроса;
 mtCustom – обычное сообщение без значка.
Параметр Buttons задает число и вид кнопок в окне. Он может
состоять из нескольких разделенных запятыми именованных констант,
записанных в квадратных скобках. Константы образуют следующее
множество: mbYes, mbNo, mbOk, mbCancel, mbAbort, mbRetry, mbIgnore,
mbAll, mbHelp. Названия кнопок совпадают с именами соответствующих
констант, но без префикса mb. Помимо списка из констант можно
использовать также следующие стандартные константы-множества:
mbOkCancel, mbYesNoCancel и mbAbortRetryIgnore. Они задают
наиболее часто используемые в диалоговых окнах комбинации
командных кнопок.
Параметр Help целого типа определяет номер раздела
справочной системы, который выводится на экран при нажатии клавиши
F1. Если использование справочной системы не предусмотрено, то
значение параметра Help берется равным нулю.
Значение,
возвращаемое
функцией
MessageDlg
или
MessageDlgPos после щелчка по одной из кнопок, позволяет определить
эту кнопку. Ниже приведен список констант, идентифицирующих
нажатую кнопку.
Константа
Нажатая кнопка
mrNone
кнопка не нажата
mrOk
OK
mrCancel
Cancel
mrAbort
Abort
mrRetry
Retry
mrIgnore
Ignore
mrYes
Yes
13
mrNo
No
mrAll
All
Задание 10. Подготовить и выполнить программу решения
квадратного уравнения. Ввод исходных данных выполнить с помощью
подпрограммы InputBox, а вывод результатов – с помощью процедуры
ShowMessage. В программе предусмотреть все варианты результатов, в
том числе когда уравнение не имеет корней.
Файловый ввод-вывод в Object Pascal базируется на
использовании файлов трех категорий: типизированных (file of <тип>),
текстовых (стандартный тип TextFile) и файлов без типа (file). Работа с
каждой из этих категорий имеет свои особенности и основывается,
прежде всего, на использовании стандартных процедур и функций для
файлов5. Нововведения в работе с файлами в языке Object Pascal состоят
в следующем:
 процедуры Assign и Close заменены соответственно
процедурами AssignFile и CloseFile;
 при объявлении текстовых файлов используется стандартное
имя типа TextFile, так как предопределенный идентификатор Text
применяется в большинстве случаев как имя свойства некоторых
компонент (например, TEdit.Text);
 в обычных приложениях DELPHI обращения к файлам Input
и Output вызывают ошибку ввода-вывода. Если же приложение
компилируется в так называемом консольном режиме6, который
устанавливается опцией Generate console application на вкладке Linker
диалогового окна ProjectOptions, то файлы стандартного вводавывода Input и Output автоматически связываются с консольным (т.е.
DOS-окном) этого приложения и могут использоваться так же, как и
раньше. Кроме того, в этом режиме могут использоваться процедуры
Assign, Close и имя типа Text.
5
Основная информация по работе с файлами приведена в [2, гл.
6
Иное название – эмуляция (воспроизведение) текстового
7].
режима.
14
Консольный режим следует использовать также при выполнении
ввода-вывода на экран с помощью стандартных процедур Read (ReadLn)
и Write (WriteLn), поскольку эти процедуры предполагают ввод-вывод
символов, а DELPHI работает в графическом режиме. Определенные
сложности возникают также с выводом на экран текстов, содержащих
символы кириллицы, или с чтением их из файла, созданного в MS DOS.
Объясняется это тем, что в текстовом режиме (и в MS DOS) используется
ASCII-кодировка, а в DELPHI (и в WINDOWS) – ANSI-кодировка, у
которых коды символов кириллицы не совпадают.
Задание 11. Подготовить и выполнить программу чтения с
экрана двух чисел и вывода на экран их суммы.
Примечание. Для решения задачи следует использовать
эмуляцию текстового режима. В этом случае приложение
компилируется в консольном режиме и работа программы будет
протекать так же, как в MS DOS.
Для решения необходимо выполнить следующие действия:
1. Открыть новый проект командой File|New Application главного
меню.
2. Установить консольный режим компиляции так, как это было
пояснено выше.
3. Открыть текст программы-проекта командой View|Project Source.
4. Скорректировать текст этой программы, удалив из него строки
между операторными скобками begin и end.
5. Ввести новый текст программы, поместив описание переменных
перед begin. В тексте для ввода исходных чисел использовать
оператор Readln, сопровождая ввод предварительным выводом на
экран имени вводимой переменной. Для вывода суммы использовать
оператор Writeln.
6. Запустить программу командой главного меню Run|Run. Учитывая
подсказки программы, ввести значения исходных чисел, заканчивая
каждый ввод нажатием Enter.
7. Получив результат, отменить консольный режим компиляции.
Задание 12. Подготовить и выполнить программу, которая
попарно читает из текстового файла находящиеся в нем целые числа и
подсчитывает число случаев, когда оба числа больше нуля.
Примечание. Для решения задачи рекомендуется следующая
последовательность действий:
1. С помощью текстового редактора DELPHI создать текстовый
файл, в который поместить 5-6 пар положительных и
отрицательных целых чисел, отделяя их друг от друга хотя бы
одним разделителем. Файл сохранить в текущем каталоге.
15
В разделе объявления переменных интерфейсной части ввести
файловую переменную типа TextFile.
3. В конце модуля формы перед end. разместить секции инициализации
и завершения, записав в них операторы, выполняющие стандартные
начальные и завершающие действия с исходным файлом.
4. Для кнопки “Операция” подготовить текст обработчика событий,
выполняющего обращение к файлу, чтение данных файла и
определение количества пар положительных чисел среди них.
Информацию о результате представить в окне сообщения.
5. Выполнить компиляцию программы и проверить ее выполнение.
Задание 13. Подготовить и выполнить программу, которая
попарно читает из текстового файла вещественные числа и, считая в
каждой паре первое число действительной, а второе – мнимой
составляющей комплексного числа, записывает их в файл комплексных
чисел.
Примечание. Для решения задачи следует использовать
программу предыдущего задания, внеся в нее следующие изменения и
дополнения:
1. В исходный текстовый файл вместо целых чисел записать
вещественные.
2. Дополнить форму приложения кнопкой “Проверка”, с помощью
которой будут проверяться результаты работы программы,
компонентой Memo, в которую результаты будут записываться и
выводиться на экран, и меткой для вывода сообщений о ходе
работы программы.
3. В разделе объявления типов модуля формы ввести тип комплексных
чисел Complex, используя для этого тип record. В разделе var
добавить файловую переменную типа файла комплексных чисел.
4. Секции инициализации и завершения дополнить операторами
открытия и закрытия файла комплексных чисел.
5. Для кнопки “Операция” подготовить текст обработчика, с
помощью которого вывести сообщение о начале работы
программы, организовать попарное чтение чисел из исходного
файла, формирование комплексных чисел и их запись в выходной
файл. Момент окончания формирования выходного файла
отметить сообщением “Файл комплексных чисел подготовлен”,
которое вывести на экран в поле метки, заменив в ней прежний
текст на новый (для перерисовки метки после изменения ее текста
можно использовать стандартный метод Repaint).
2.
16
Для кнопки “Проверка” подготовить текст обработчика событий,
с помощью которого выполняются чтение файла комплексных
чисел, преобразование действительной и мнимой составляющей
каждого числа в символьную форму, дополнение каждой из них
пояснениями типа ‘Re=’ и ‘Im=’ и вывод полученной строки
символов в компоненту Memo.
Выполнить компиляцию и проверку работы программы,
последовательно нажимая кнопки “Операция”, “Проверка”, “Закрыть’.
6.
9. Процедуры и функции
В языке Object Pascal, как и в обычном Паскале, имеется две
разновидности подпрограмм – процедуры и функции. Их виды, правила
описания и использования сохраняются. В Object Pascal имеются
следующие отличия в реализации процедур и функций:
1. Функция может возвращать значения практически любых
типов (стандартных и пользовательских), за исключением
файловых и объектных типов прежней объектной модели.
2. Для возврата результата из функции введена специальная
переменная Result, которая представляет собой неявно
объявленную локальную переменную, имеющую такой же
тип, как и возвращаемое функцией значение.
3. Введено новое языковое средство – конструкторы открытых
параметров-массивов, которые позволяют формировать
передаваемый в процедуру фактический параметр-массив
непосредственно в операторе вызова процедуры. При этом
не требуется объявления массива в вызывающей программе
и его предварительного заполнения исходными значениями.
4. В качестве открытого массива можно использовать массив с
компонентами
разного
типа.
В
этом
случае
соответствующему формальному параметру задается тип
array
of
const,
что
позволяет
передавать
в
процедуру/функцию произвольное число фактических
параметров различных типов с сохранением их исходного
типа в рамках процедуры/функции.
Открытые массивы рассматриваются в [2, с. 196]. Для работы с
ними используются следующие стандартные функции: функции High(X)
и Low(X) определяют соответственно максимальный и минимальный
индексы массива открытого типа X, а функция Slice(X,C) выделяет из
массива X первые C компонент (типа Integer) для передачи их в
подпрограмму в качестве открытого массива.
17
Конструктор открытого массива аналогичен конструктору
множества, только используемые в нем выражения должны иметь тот же
тип, что и компоненты открытого массива. Любой конструктор
открытого массива помещается в квадратные скобки и представляет
собой перечисленные через запятую выражения соответствующего типа,
например: Max([A, 1.15, B+C]), где Max – имя функции.
Задание 14. Подготовить и выполнить программу, которая
читает из текстового файла записанные в него целые числа, помещает
их в массив открытого типа, выделяет в нем первые 5 элементов и
среди них отыскивает элемент с наибольшим значением.
Примечание. Исходный файл использовать из программы
задания 12. Определение максимального элемента массива выполнить с
помощью функции, у которой в качестве передаваемого параметра
используется массив открытого типа.
10. Отчет по лабораторной работе
Отчет следует оформить как документ MS Word. Он должен
содержать:
1. Исходные тексты программ по всем заданиям практической
части с комментариями.
2. Формы программы, демонстрирующие все результаты ее
выполнения 7
Литература
1. Марченко А. И. Программирование на языке Object Pascal 2.0.
- К.:ЮНИОР,1998.
2. Фаронов В.В. Delphi 3.:Учебный курс. – М.: Нолидж, 1998.
3. Архангельский А. Я. Delphi 7. БИНОМ, 2003.
Приложение 1
Стандартные подпрограммы преобразования типов
Chr(X) - преобразовать число в символ
Функция возвращает символ типа Char, кодом которого является
число Х типа Byte.
FloatToStr(Value) - преобразовать вещественное число в
символьное представление
Функция возвращает строку типа string, содержащую
символьное представление вещественного числа Value типа Extended.
Для быстрой фиксации форм рекомендуется использовать
программу Snagit.
7
18
Hi(X) - выделить старший байт из числа
Функция выделяет старший байт из числа Х (любого целого
типа) и возвращает его как результат своей работы. Тип возвращаемого
результата -Byte.
lntToHex(Value, Digits) - преобразовать целое число в
шестнадцатеричную символьную форму
Функция преобразовывает число Value типа Integer в строку
символов, представляющих его в шестнадцатеричной форме. Параметр
Digits типа Integer задает число цифр в этом представлении числа.
Полученную строку функция возвращает как результат своей работы.
IntToStr(Value) - преобразовать целое число в десятичную
символьную форму
Функция преобразовывает число Value типа Integer в строку
символов, представляющих его в десятичной форме. Полученную строку
функция возвращает как результат своей работы.
Lo(X) - выделить младший байт из числа
Функция выделяет младший байт из числа Х (любого целого
типа) и возвращает его как результат своей работы. Тип возвращаемого
результата - Byte.
Ord(X) - определить порядковый номер величины
Функция возвращает порядковый номер (типа Longint) величины
Х порядкового типа.
Ptr(Address) - преобразовать адрес в указатель
Функция преобразовывает адрес Address типа Integer в указатель
типа Pointer и возвращает его как результат своей работы.
Round(X) - округлить вещественное число до ближайшего
целого
Функция возвращает целое число типа Longint, представляющее
собой округленное до ближайшего целого вещественное число Х типа
Extended.
Str(X, S) - преобразовать двоичное число в символьное
представление
Процедура преобразовывает число Х любого целого или
вещественного типа в строку S.
StringToWideChar(Source, Dest, DestSize) - преобразовать
строку с ANSI-символами в строку с UNICODE-символами
Функция преобразовывает строку Source типа string в строку
типа PWideChar и помещает ее в переменную Dest типа PWideChar и
размером DestSize (типа Integer}. Функция возвращает указатель типа
PWideChar на сформированную строку.
StrToFloat(S)
преобразовать
символьную
форму
вещественного числа в двоичную
19
Функция преобразовывает строку S типа string в двоичное
представление вещественного числа типа Extended и возвращает это
число как результат своей работы.
StrTolnt(S) - преобразовать символьную форму целого числа
в двоичную
Функция возвращает двоичный эквивалент типа Integer
символьной формы числа (десятичной или шестнадцатеричной),
представленной строкой S.
StrToIntDef(S, Default) - преобразовать символьную форму
числа в двоичную
Функция аналогична функции StrToInt. Если последовательность
символов не представляет собой число, возвращается значение Default
(типа Integer}.
Trunc(X) - выделить целую часть вещественного числа
Функция возвращает целое число типа Longint, представляющее
собой целую часть вещественного числа Х типа Extended.
Val(S, V, Code) - преобразовать символьную форму числа в
двоичную
Процедура преобразовывает форму числа, представленную
строкой S, в двоичную в соответствии с типом параметра V. Этот
параметр может быть любого целого или вещественного типа. Если
преобразование прошло успешно, в переменной Code типа Integer будет
число 0, в противном случае здесь будет номер первого неправильного
символа.
WideCharLenToString(Source, SourceLen) - преобразовать
строку с UNICODE-символами в строку с ANSI-символами
Функция формирует из строки Source типа PWideChar,
содержащей UNICODE-символы, строку типа string с ANSI-символами.
При этом берутся только SourceLen (типа Integer) первых символов
исходной строки.
WideCharLenToStrVar(Source,
SourceLen,
Dest)
преобразовать строку с UNICODE-снмволамм • строку с ANSIсммволамн
Процедура формирует из строки Source типа PWideChar,
содержащей UNICODE -символы строку типа string с ANSI-символами и
помещает ее в переменную Dest типа string. При этом берутся только
SourccLen (типа Integer) первых символов исходной строки.
WideCharToString(Source) - преобразовать строку с
UNICODE-сямволами в строку с ANSI-символами
Функция аналогична функции WideCharLenToString, однако
преобразовываются все символы исходной строки.
20
WideCharToStrVar(Souree, Dest) - преобразовать строку с
UNICODE-сямволамм в строку с ANSI-символами
Процедура аналогична процедуре WideCharLenToStrVar,
однако преобразовываются все символы исходной строки.
Приложение 2
Стандартные подпрограммы для "коротких" и "длинных"
строк
В модулях System и SysUtils определены стандартные
подпрограммы работы с "короткими" и "длинными" строками. Для всех
этих подпрограмм существуют общие правила:
 если для заданных параметров недостаточно символов
какой-либо строки, то берется только имеющееся количество
символов;
 если количество размещаемых символов больше области
строки, предназначенной для них, размещается только допустимое
количество символов, а остальные отбрасываются.
AnsiCompareStr(Sl, S2) - сравнение двух строк
Функция сравнивает две строки типа string и возвращает
отрицательное число типа Integer, если первая строка меньше второй,
число 0, если строки равны, и положительное число, если первая строка
больше второй. Сравнение выполняется с учетом региональной
установки Windows.
AnsiCompareText(Sl, S2) • сравнение двух строк
Функция аналогична функции AnsiCompareStr, только при
сравнении строк не делается разницы между прописными и строчными
буквами. Сравнение выполняется с учетом региональной установки
Windows.
AnsiLowerCase(S) - получить строку со строчными буквами
Функция формирует из строки S типа string строку того же типа,
в которой все прописные буквы заменены на строчные, и возвращает ее
как результат своей работы. Преобразование выполняется с учетом
региональной установки Windows.
AnsiUpperCase(S) - получить строку с прописными буквами
Функция формирует из строки S типа string строку того же типа,
в которой все строчные буквы заменены на прописные, и возвращает ее
как результат своей работы. Преобразование выполняется с учетом
региональной установки Windows.
CompareStr(Sl, S2) - сравнение двух строк
21
Функция сравнивает две строки типа string и возвращает
отрицательное число типа Integer, если первая строка меньше второй,
число 0, если строки равны, и положительное число, если первая строка
больше второй. Сравнение выполняется без учета региональной
установки Windows.
CompareText(Sl, S2) - сравнение двух строк
Функция аналогична функции CompareStr, только при сравнении
строк не делается разницы между прописными и строчными буквами.
Сравнение выполняется без учета региональной установки Windows.
Concat(Sl [, S2, S3 ,..., SN]) - объединить несколько строк
Функция объединяет строки S1, S2 ,..., SN в одну и возвращает
полученную строку как результат своей работы. Количество
объединяемых строк может быть любым. Сами исходные строки при
этом не изменяются.
Copy(S, Index, Count) - выделить часть строки
Функция выделяет часть строки S в Count (тип Integer) символов,
начиная с символа с индексом Index (тип Integer). Полученная строка
возвращается функцией как результат ее работы. Сама строка S при этом
не изменяется.
Delete(S, Index, Count) - удалить часть строки
Процедура удаляет из строки S Count (тип Integer) символов,
начиная с символа с индексом Index (тип Integer).
Insert(Source, S, Index) - поместить в строку другую строку
Процедура помещает строку Source в строку S, начиная с
позиции Index (тип Integer). Новая строка не замещает символы строки S,
а "отодвигает" их к концу полученной строки.
Length(S) - получить длину строки
Функция возвращает длину (тип Integer) строки в символах.
LoverCase(S) - получить строку со строчными буквами
Функция формирует строку, аналогичную строке S, но у которой
все прописные буквы заменены строчными. Эта строка возвращается в
качестве результата. Функция преобразовывает в строчные только
прописные буквы латинского алфавита.
Pos(Substr, Str) - найти вхождение одной строки в другой
Функция ищет вхождение строки Substr в строке Str и
возвращает начало первого вхождения (номер первого символа - тип
Integer). Если такого вхождения нет, функция возвращает значение 0.
SetLength(S, NewLength) - задать новую длину строки
Процедура задает новую длину NewLength типа Integer строке S.
Если строка S "короткая", устанавливается значение S[0] в
Chr(NewLength). Для "длинных" строк выделяется новая область
22
динамической памяти соответствующего размера, куда помещается
информация из старой строки.
SetString(S, Buffer, Len) - задать содержимое строки и ее
длину
Процедура задает содержимое и длину строки S. Если S "короткая" строка, компоненте S[0] присваивается значение Chr(Len),
после чего, если параметр Buffer типа PChar не равен nil, в строку S из
буфера Buffer копируется Len символов. Если же параметр Buffer равен
nil, никакие символы в строку S не копируются. Если S "длинная" строка,
под нее выделяется новая динамическая область соответствующего
размера, и в нее из буфера Buffer помещаются Len символов (если только
параметр Buffer не равен nil, в противном случае область только
выделяется).
StringOfChar(Ch, Count) - заполнить строку символами
Функция возвращает строку типа string, заполненную Count
(типа Integer) символами Сh (типа Char).
Trim(S) - удалить начальные и заключительные пробелы
Функция формирует из строки S новую строку с удаленными
начальными и заключительными пробелами и управляющими символами
(с кодами до 31 включительно) и возвращает ее как результат своей
работы. Сама строка S при этом не изменяется.
TrimLeft(S) - удалить начальные пробелы
Функция аналогична функции Trim, только удаляются лишь
начальные пробелы и управляющие символы.
TrimRight(S) - удалить заключительные пробелы
Функция аналогична функции Trim, только удаляются лишь
заключительные пробелы и управляющие символы.
UpCase(Ch) - преобразовать символ в прописной
Функция преобразовывает символ Ch в прописной и возвращает
его как результат своей работы. Функция преобразовывает только
строчные буквы латинского алфавита, остальные символы возвращаются
функцией без изменения.
UpperCase(S) - получить строку с прописными буквами
Функция формирует строку, аналогичную строке S, но у которой
все строчные буквы заменены прописными. Эта строка и возвращается
функцией в качестве результата ее работы. Функция преобразовывает в
прописные только буквы латинского алфавита.
23
Лабораторная работа № 2
Принципы объектно-ориентированного проектирования
программ в среде DELPHI
1. Введение
Объектно-ориентированное проектирование программ или
просто
объектно-ориентированное
программирование
(ООП)
представляет собой качественно новый шаг в развитии современных
методов программирования. Настоящая работа посвящена знакомству с
принципами ООП применительно к программированию в среде DELPHI.
Любая программа в широком смысле может рассматриваться как
модель8 (воспроизведение или отражение) части реального мира
(внешней среды, предметной области).
Различные образования реального мира могут быть определены
единым термином: объекты. К ним относятся окружающие нас в быту
предметы, технические устройства, сооружения, животные и, наконец,
сами люди. Каждый объект характеризуется только присущим ему
набором (множеством) параметров (свойств), а также множеством
действий, которые может выполнить сам объект и которые могут быть
выполнены над данным объектом другими объектами.
Ко всем объектам реального мира может быть применена единая
по смыслу функция классифицирования, результатом выполнения
которой является разбиение объектов на группы по различным
признакам, видам и свойствам. В связи с этим можно ввести в
рассмотрение понятие классов (групп) объектов. Это понятие определяет
множество различных свойств объектов и множество различных
действий (операций) над ними.
Любая схема (или система) классифицирования обычно строится
по принципу от “общего” к “частному” и, как правило, имеет
многоуровневую структуру отношений, в которой элементы высших
ступеней порождают (производят) элементы низших уровней. Эти
элементы имеют свои конкретные особенности и одновременно
получают все основные свойства и действия, то есть “наследуют” их от
элементов верхнего уровня. Например, реальный объект стол обладает
множеством различных свойств, таких как тип (обеденный, книжный,
8
Модель – некоторое физическое или логическое
(искусственное или естественное) образование (предмет или явление),
которое обладает свойствами и поведением, подобными (сходственными)
свойствам и поведению другого образования, называемого оригиналом
(аналогом).
24
кухонный), габариты, цвет, тип древесины и т. д. К нему применимы
различные действия: стол можно изготовить, смонтировать (собрать),
ремонтировать, передвигать, демонтировать и т. д. Очевидно, что
конкретный стол, как объект реального мира, можно считать
принадлежащим к классу столов, который определяет общие
характеристики всех столов. В свою очередь класс столов можно считать
порождением элемента верхнего уровня, а именно класса мебели, все
свойства которого одновременно являются и свойствами класса столов.
Это означает, что класс столов “наследует” свойства и действия класса
мебели. Далее можно рассмотреть класс изделий, в который будет
включен класс мебели. О классе изделий и классе мебели можно сделать
такие же заключения, что и о классах мебели и столов.
Продолжая аналогичные рассуждения, можно создать сложную
иерархическую структуру отношений классов различных объектов
реального мира. Все они могут найти свое отражение в компьютерных
программах, так как любая программа взаимодействует с внешней
средой, получая из нее исходные данные и выдавая в нее (точнее,
сохраняя в ней) результаты.
В известных ранее традиционных языках и системах
программирования также существует соответствие между объектами
программы (переменные, операторы и т.д.) и объектами реального мира.
В отличие от этих систем, в ООП вводятся новые, более широкие по
смыслу и назначению понятия и объекты, которые позволяют
программисту точнее и глубже отражать сложную структуру отношений
различных объектов реального мира и, следовательно, создавать более
совершенные и эффективные программы.
ООП обладает рядом преимуществ, к которым, в частности,
можно отнести:
 использование
более естественных с точки зрения
повседневной практики понятий и простота введения новых
понятий;
 возможность создания и использования библиотек классов
(примером такой библиотеки является, в частности,
библиотека компонент DELPHI):
 параллельная
разработка
визуальных
средств
взаимодействия с пользователем и средств, реализующих
алгоритмическую часть задачи и т. д.
Вместе с тем следует отметить, что все эти преимущества и
эффективность ООП проявляются в полной мере только при разработке
больших программ или классов программ.
25
2. Основные понятия ООП
2.1. Классы
В основе ООП лежат понятия класса и его физической
реализации – объекта.
Класс – это сложная структура (аналогичная типу), включающая
в себя, помимо описания данных, описание подпрограмм (процедур и
функций), которые могут быть выполнены над объектом, а также
характеристики данных и подпрограмм.
Данные класса называются полями, подпрограммы –
методами, а характеристики данных и подпрограмм – свойствами.
Обычно классы задаются в разделе объявления типов тех или
иных модулей, и, чтобы их можно было использовать в программе и
других модулях, эти объявления должны быть сделаны в интерфейсе
модуля.
Класс объявляется на основе общего правила задания типов.
Описание структуры класса в языке Оbjеct Pascal начинается с
зарезервированного слова class, после которого в круглых скобках
указывается имя родительского класса. Если он не указан, то
предполагается, что родительским является класс TОbjеct, который в
ООП-модели языка Object Pascal по умолчанию считается предком всех
объявленных классов. Далее в виде отдельных строк записываются поля
данных, методы и свойства. Завершается описание класса
зарезервированным словом end. Если ни одного поля, метода или
свойства у объявляемого класса нет, но указан непосредственный предок
класса, зарезервированное слово end в конце объявления можно не
писать. Последовательность записи отдельных элементов (поля, методы,
свойства) класса безразлична (с учетом возможности использования
одними элементами других), однако чаще всего сначала записываются
поля, затем методы и, наконец, свойства.
Пример описания простого класса 9:
TTPerson=class
private
fname:string[15];
faddress:string[35];
public
procedure show;
end;
Согласно принятому в DELPHI соглашению имена классов
обычно (но необязательно!) начинаются с префикса T, а имена полей – с
префикса F (или f). Смысл ключевых слов private, public поясняется
ниже.
9
26
В приведенном примере TTPerson – это имя класса, fname и
faddress – имена полей, show – имя метода.
Для методов в объявлении класса записываются только их
заголовки. Само же тело методов описывается впоследствии - в
исполнительной части модуля - так же, как это делается для подпрограмм
в модулях.
В ряде случаев может оказаться, что два класса используют
характеристики друг друга. В этом случае приходится использовать
опережающее объявление одного из этих классов, аналогично тому, как
это делается для подпрограмм с использованием директивы forward. При
опережающем объявлении сначала записывается лишь имя класса и через
знак равенства - зарезервированное слово class, например:
TObject = class;
Далее по тексту предварительно объявленный класс должен быть
описан полностью в подходящем месте программы так же, как это
делается без предварительного объявления.
Отдельные элементы класса могут иметь различные
возможности по их использованию вне рассматриваемого класса (иметь
разные области доступности или, иначе, видимости). В ООП DELPHI
имеется несколько вариантов задания областей видимости, которые
определяют разделы (секции) в описании класса и начинаются с
ключевых слов private, public, protected, published и automated.
Количество и порядок следования этих разделов могут быть
произвольными. Семантика разделов видимости рассматривается в п. 2.6.
Общую структуру описания класса можно представить
следующим образом:
type
ИмяКласса = class(ИмяРодительскогоКласса)
Опубликованные поля, методы, свойства;
private
Скрытые поля, методы, свойства;
public
Общедоступные поля, методы, свойства;
protected
Защищенные поля, методы, свойства;
published
Опубликованные поля, методы, свойства;
automated
Поля, методы, свойства для OLE-объектов;
end;
27
2.2 Объекты
В программе представители класса — объекты, объявляются в
разделе var. Например, так:
var
student:TTPerson;
professor:TTPerson;
Примечание. В дальнейшем все основные понятия ООП
рассматриваются на примере решения задачи составления списков
преподавателей и студентов некоторой кафедры вуза. Здесь и далее
приводятся фрагменты программы решения этой задачи.
Следует обратить особое внимание на то, что в Object Pascal
объект — динамическая структура. Переменная-объект содержит не
данные, а ссылку на данные объекта. Поэтому программист должен
позаботиться о выделении памяти для этих данных и задании для них
начальных значений.
Выделение памяти и инициализация объекта осуществляются с
помощью специального метода класса — конструктора, которому обычно
присваивают имя create (создать). Чтобы подчеркнуть особую роль и
поведение конструктора, вместо ключевого слова procedure в заголовке
конструктора используется слово constructor. Ниже приведено описание
класса TTPerson, в состав которого введен конструктор.
TTPerson = class
private
fname:string[15];
faddress:string[35];
constructor create; // конструктор
public
procedure show; // метод
end;
Выделение памяти для данных объекта происходит
присваиванием результата применения метода-конструктора к типу
(классу) объекта. Например, после выполнения оператора
professor:=TTPerson.create;
выделяется необходимая память для данных объекта professor.
Помимо выделения памяти, конструктор, как отмечено выше,
решает задачу присваивания полям объекта начальных значений, т. е.
осуществляет инициализацию объекта. Ниже приведен пример
реализации конструктора для объекта TTPerson.
constructor TTPerson.create;
begin
fname:=’’;
faddress:=’’;
28
end;
Реализация конструктора несколько необычна. Во-первых, в теле
конструктора нет привычных операторов New, обеспечивающих
выделение динамической памяти (всю необходимую работу по
выделению памяти выполняет компилятор). Во-вторых, формально
конструктор не возвращает значения, хотя в программе обращение к
конструктору осуществляется как к методу-функции.
После объявления и инициализации объект можно использовать,
например установить значение поля объекта. Доступ к полю объекта
осуществляется указанием имени объекта и имени поля, которые
отделяются друг от друга точкой. Хотя объект является ссылкой, однако
правило доступа к данным с помощью ссылки, согласно которому после
имени переменной, являющейся ссылкой, надо ставить значок ^, на
объекты не распространяется. Например, для доступа к полю fname
объекта professor вместо
professor^.fname следует писать professor.fname
Если в программе некоторый объект больше не используется, то
можно освободить память, занимаемую полями этого объекта. Для
выполнения этого действия используют метод-деструктор free.
Например, чтобы освободить память, занимаемую полями объекта
professor, достаточно записать
professor.free;
2.3. Методы
Методы - это процедуры и функции, объявление которых
включено в описание класса и которые выполняют действия над
объектами класса. Объявляются и описываются они так же, как и
обычные подпрограммы в модулях, то есть в интерфейсной части модуля
внутри описания класса записывается лишь заголовок подпрограммы, а в
исполнительной части – само содержание метода. Чтобы метод был
выполнен, надо указать имя объекта и имя метода, отделив одно имя от
другого точкой. Например, оператор
professor.show;
вызывает применение метода show к объекту professor.
Фактически оператор применения метода к объекту — это
специфический способ записи оператора вызова процедуры.
В программе методы определяются точно так же, как обычные
процедуры и функции, за исключением того, что имя процедуры или
функции, являющейся методом, состоит из двух частей: имени класса, к
которому принадлежит метод, и имени метода. Имя класса от имени
метода отделяется точкой.
29
Ниже приведен пример определения метода show описанного
выше класса ТТРегson.
// метод show класса TTPerson
procedure ТТРегson.show;
begin
ShowMessage(‘Имя:’+fname+#13+'Адрес:'+faddress);
end;
Следует обратить внимание на то, что в операторах метода
доступ к полям объекта осуществляется без указания имени объекта.
Обычно методы применяются к ранее созданным объектам
программы. Такие методы можно считать методами объектов. В DELPHI
существует возможность создания методов, которые можно использовать
даже тогда, когда ни один объект класса не создан. К таким методам
относятся, например, конструкторы, которые вызываются для создания
объектов. Подобные методы называются методами класса и особым
образом оформляются (за исключением конструкторов, о которых
сказано
выше).
Объявление
такого
метода
начинается
с
зарезервированного слова class, после которого следует обычное
объявление метода, например:
TMyForm = class(TForm)
class procedure MessageCreate;
end;
…
class procedure TMyForm.MessageCreate;
begin
…
end;
Вызывается такой метод либо как метод класса, тогда перед
именем метода в качестве квалификатора записывается тип класса, либо
как метод объекта. В этом случае он ничем не отличается от обычных
методов: имя его используется либо без квалификатора, если метод
вызывается внутри объекта, либо с квалификатором, в качестве которого
выступает имя объекта, если метод вызывается извне объекта.
2.4. Инкапсуляция и свойства объекта
Под инкапсуляцией понимается скрытие полей объекта с целью
обеспечения доступа к ним только посредством методов класса.
В Object Pascal ограничение доступа к полям объекта
реализуется с помощью свойств объекта. Свойство объекта
характеризуется полем, хранящим значение свойства, и двумя методами,
обеспечивающими доступ к полю свойства. Метод установки значения
свойства называется методом записи свойства (write), метод получения
значения свойства называется методом чтения свойства (read).
30
В описании класса перед именем свойства записывают ключевое
слово property (свойство). После имени свойства указываются его тип,
затем имена методов, обеспечивающих доступ к значению свойства.
После слова read указывается имя метода, обеспечивающего чтение
свойства, после слова write —имя метода, обеспечивающего запись
свойства. Ниже приведен пример описания класса TTPerson,
содержащего два свойства: Name и Address.
type
TName=string[15];
TAddress=string[35];
TTPerson = class
private
FName:Tname; //значение свойства Name
FAddress:TAddress; // значение свойства Address
Constructor Create(Name:Tname);
Procedure Show;
Function GetName:TName;
Function GetAddress:TAddress;
Procedure SetAddress(NewAddress:TAddress);
public
Property Name: Tname
read GetName;
Property Address: TAddress
read GetAddress;
write SetAddress;
end;
В программе для установки значения свойства необязательно
записывать оператор применения к объекту метода установки значения
свойства, можно записать обычный оператор присваивания значения
свойству. Например, чтобы присвоить значение свойству Address объекта
student, достаточно записать
student.Address:=’С.Петербург, ул. Садовая, 21, кв.3’;
Компилятор
перетранслирует
приведенный
оператор
присваивания значения свойству в оператор вызова метода:
student.SetAddress('С.Петербург, ул. Садовая, 21, кв.3');
Внешне использование свойств в программе ничем не отличается
от использования полей объекта. Вместе с тем между свойством и полем
объекта существует принципиальное отличие: при присвоении и чтении
значения свойства автоматически вызывается процедура, которая
выполняет некоторую работу.
31
В программе на методы свойства можно возложить некоторые
дополнительные задачи. Например, с помощью метода можно проверить
корректность присваиваемых свойству значений, установить значения
других, логически связанных со свойством, полей, вызвать
вспомогательную процедуру.
Оформление данных объекта как свойства позволяет ограничить
доступ к полям, хранящим значения свойств объекта, например можно
разрешить только чтение. Чтобы операторы программы не могли
изменить значение свойства, в описании свойства надо указать только
имя метода чтения. Попытка присвоить значение свойству,
предназначенному только для чтения, вызывает ошибку времени
компиляции В приведенном выше описании класса TTPerson свойство
Name доступно только для чтения, а свойство Address — для чтения и
записи.
Установить значение свойства, защищенного от записи, можно
во время инициализации объекта. Ниже приведены методы класса
TTPerson, обеспечивающие создание объекта класса TTPerson и доступ к
его свойствам.
//конструктор объекта TTPerson
Constructor TTPerson.Create(Name:TName);
begin
Fname:=Name;
end;
//метод получения значения свойства Name
Function TTPerson.GetName;
begin
Result:=FName;
end;
//метод получения значения свойства Address
Function TTPerson.GetAddress;
begin
Result:=FAddress;
end;
//метод изменения значения свойства Address
Procedure TTPerson.SetAddress(NewAddress:TAddress);
begin
if FAddress =’’
then FAddress:=NewAddress;
end;
32
Приведенный конструктор объекта TTPerson создает объект и
устанавливает значение поля FName, определяющего значение свойства
Name.
Операторы программы, обеспечивающие создание объекта
класса TTPerson и установку его свойства, могут быть, например, такими:
student:=TTPerson.create('Иванов');
student.address:=’ул. Садовая, д.21, кв. 3’;
2.5. Наследование
Концепция
объектно-ориентированного
программирования
предполагает возможность определять новые классы посредством
добавления полей, свойств и методов к уже существующим классам.
Такой механизм получения новых классов называется порождением. При
этом новый, порожденный, класс (класс-потомок) наследует свойства и
методы своего базового, родительского класса.
В объявлении класса-потомка указывается класс родителя.
Например, класс TEmployee (сотрудник) может быть порожден от
рассмотренного выше класса TTPerson путем добавления поля
Department (отдел). Объявление класса TEmployee в этом случае может
выглядеть так:
TEmployee = class(TTPerson)
FDepartment:integer; // номер отдела
constructor Create(Name:TName;Dep:integer);
end;
Заключенное в скобки имя класса TTPerson показывает, что
класс TEmployee является производным от класса TTPerson. В свою
очередь, класс TTPerson является базовым для класса TEmployee.
Класс TEmployee имеет свой собственный конструктор, который
обеспечивает инициализацию класса родителя и своих полей. Пример
реализации конструктора класса TEmployee:
constructor TEmployee.Create(Name:Tname;Dep:integer);
begin
inherited Create(Name);
FDepartment:=Dep;
end;
В приведенном примере директивой inherited вызывается
конструктор родительского класса, затем присваивается значение полю
класса потомка.
После создания объекта производного класса в программе можно
использо-. вать поля и методы родительского класса. Ниже приведен
фрагмент программы, демонстрирующей эту возможность:
engineer:=TEmployee.create('Сидоров',413);
engineer.address:='ул.Блохина, д.8, кв.10';
33
Первый оператор создает объект типа TEmployee. Второй
устанавливает значение свойства, которое относится к родительскому
классу.
2.6. Области видимости в классах
Как отмечалось в п. 2.1, помимо объявлений элементов класса
(полей, методов, свойств) описание класса, как правило, содержит
несколько директив, которые устанавливают степень видимости
элементов класса в программе.
Рассмотрим семантику директив видимости.
1. Директива private.
Поля, свойства и методы, описанные в разделе private,
называются личными или закрытыми. Сюда помещаются элементы (чаще
всего поля), которые выполняют в объекте специфичные функции и
которые поэтому целесообразно скрыть от других частей программы,
либо такие элементы, для которых по ряду причин не следует разрешать
доступ извне объекта.
2. Директива public.
Элементы, описанные в разделе public, называются
общедоступными. Они могут быть использованы всюду в программе.
Поля, свойства и методы, расположенные сразу после заголовка класса,
при выключенной директиве компилятора {$M-}, по умолчанию
принимаются общедоступными.
3. Директива protected.
Элементы
класса, объявленные
в
разделе
protected
(защищенный), доступны только в классах, порожденных от исходного.
Здесь
размещаются
элементы,
которые
важны
лишь
для
функционирования объектов данного класса и его потомков. Обычно в
секцию protected помещаются описания методов класса.
4. Директива published.
Поля, свойства и методы, описанные в разделе published,
называются опубликованными. Их область видимости эквивалентна
области видимости общедоступных описаний. Отличие состоит в том,
что информация о них, за исключением ряда типов, например real, на
этапе проектирования программы помещается в инспектор объектов.
Описания, расположенные сразу после заголовка класса, при включенной
директиве компилятора {$M+}, по умолчанию принимаются
опубликованными.
5. Директива automated.
Элементы класса, объявленные в разделе automated, называются
автоматическими. Их область видимости эквивалентна области
видимости общедоступных описаний. Отличие состоит в том, что для
автоматических свойств и методов генерируется дополнительная
34
информация, которая используется для реализации OLE-механизма.
Использовать директиву automated имеет смысл при объявлении
потомков стандартного класса TAutoObject.
Ниже приведено описание класса TTPerson, в которое включены
директивы видимости.
ТТРегsоп = class
private
FName:TName;
{ значение свойства Name }
FAddress:TAddress; ( значение свойства Address}
protected
Constructor Create(Name:TName);
Function GetName:TName;
Function GetAddress:TAddress;
Procedure SetAddress (NewAddress: TAddress);
Property Name:TName
read GetName;
Property Address:TAddress
read GetAddress
write SetAddress;
end;
Примечание.
Если необходимо, чтобы элементы класса были скрыты
полностью, определение класса следует поместить в отдельный модуль.
2.7. Полиморфизм и виртуальные методы
Полиморфизм — это возможность использовать одинаковые
имена для методов, входящих в различные классы.
Концепция полиморфизма обеспечивает при применении метода
к объекту использование именно того метода, который соответствует
классу объекта.
Пусть определены три класса, один из них является базовым для
двух других:
type
// базовый класс
TPerson=class
fname:string;{ имя }
constructor Create(name:string);
function info: string; virtual;
end;
// производный от базового TPerson
TStud=class(TPerson)
fgr:integer; { номер группы }
constructor Create(name:string;gr:integer);
35
function info: string; override;
end;
// производный от базового TPerson
TProf=class(TPerson)
fdep:string; { название кафедры }
constructor Create(name:string;dep:string);
function info: string; override;
end;
В каждом из этих классов определен метод info. В базовом
классе с помощью директивы virtual метод info объявлен виртуальным.
Объявление метода виртуальным дает возможность дочернему классу
произвести замену виртуального метода своим собственным. В каждом
дочернем классе определен свой метод info, который замещает
соответствующий метод родительского класса. При этом метод
порожденного класса, замещающий виртуальный метод родительского
класса, помечается директивой override. Ниже приведено определение
метода info для каждого класса.
function TPerson.info:string;
begin
result:=’’;
end;
function TStud.info:string;
begin
result:=fname+' гp.'+IntTostr(fgr);
end;
function TProf.info:string;
begin
result:=fname+'каф.'+fdep;
end;
В программе список людей можно представить массивом
объектов класса TPerson, например
1ist:array[1..SZL] of TPerson; // SZL — размер массива
Здесь следует отметить, что объект list— это массив указателей.
Объявить подобным образом список можно потому, что Object Pascal
позволяет указателю на родительский класс присвоить значение
указателя на дочерний класс. Поэтому элементами массива list могут
быть как объекты класса TStud, так и объекты класса TProf.
Вывод списка можно осуществить применением метода info к
элементам массива, например, так:
36
st:=’’;
for i:=l to SZL do
if list[i] <> NIL
then st:=st+info.list[i]+#13;
ShowMessage(st);
Во время работы программы каждый элемент массива может
содержать как объект типа TStud, так и объект типа TProf. Концепция
полиморфизма обеспечивает возможность применения к объекту именно
того метода, который соответствует типу объекта.
Задание 1. Подготовить и выполнить программу, в которой
формируется и выводится список студентов и преподавателей с
использованием рассмотренных выше объявлений классов TPerson, TStud
и TProf.
Решение задачи выполнить в следующей последовательности:
1.
Открыть новый проект командой главного меню
File|New Application и в качестве заголовка ввести текст “Студенты и
преподаватели”.
2.
Создать главную форму, поместив на нее со страницы
Standard следующие компоненты:

две компоненты типа Edit, разместив их в правой
верхней части окна формы. Исходное содержимое компонент удалить.
Первая компонента будет использоваться для ввода фамилии студента
или преподавателя, а вторая – для ввода номера группы или названия
кафедры;

слева от каждой строки ввода поместить по
компоненте типа Label. Первой метке задать значение “Фамилия”, а
второй – “Группа или кафедра’;

в левой нижней части формы поместить компоненту
типа GroupBox без названия, задав ей размеры, соответствующие
примерно 1/5 площади формы;

внутри компоненты GroupBox поместить две
компоненты типа RadioButton (переключатели) с названиями: первая –
“студент”, вторая – “преподаватель”;

справа от компоненты GroupBox поместить две кнопки
с названиями “Добавить в список” и “Вывести список”.
3.
В интерфейсной части модуля ввести следующие
разделы:

раздел
описания
типов
(помимо
основного,
автоматически создаваемого средой), в котором разместить описания
классов TPerson, TStud и TProf из п. 2.7;

раздел констант, задав в нем максимальный размер
списка-массива элементов типа TPerson (не более 10-12);
37

в раздел var добавить описание массива объектов
класса TPerson (см. п. 2.7) и описание переменной, определяющей
текущее число людей в списке.
4.
В исполнительную часть модуля поместить описания
следующих методов:

метода класса TPerson, обеспечивающего создание
объекта этого класса и доступ к его свойствам (см. п. 2.4);

методов классов TStud и TProf c использованием
обращения к конструктору родительского класса TPerson (см. п. 2.5);

метода info для классов TPerson, TStud и TProf (см. п.
2.7).
5.
В эту же часть модуля поместить описания следующих
обработчиков:

обработчика, который запускается нажатием кнопки
“Добавить в список”. Он должен в зависимости от состояния
переключателей “студент”, “преподаватель” формировать массив
элементов класса TStud или TProf. При этом фамилии должны
вводиться в первой строке ввода, а номер группы или название кафедры
– во второй. Ввод должен выполняться в соответствии с заданным
максимальным размером списка;

обработчика, который выполняется в результате
нажатия на кнопку “Вывести список” Он должен применять метод info
к каждому объекту списка и выводить список (см. п. 2.7).
6.
Выполнить сохранение и компиляцию файла программы.
7.
Проверить работу программы в двух случаях:
a)
формирование и вывод списка студентов (на примере
своей группы);
b)
формирование и вывод списка преподавателей кафедры
(например, ЭВМ).
3. Классы и объекты DELPHI
DELPHI содержит сложную иерархию классов, которые можно
использовать в программе, создавая объекты этих классов или формируяклассы потомки. В начале этой иерархии стоят классы, называемые
абстрактными классами. Для них нельзя создать полноценные
работающие объекты, но они являются родоначальниками целых
семейств классов, для которых такие объекты уже могут быть созданы.
Исходя из свойства наследования, в абстрактных классах помещены
характеристики, присущие всем классам их семейств.
38
Структура некоторых абстрактных классов, находящихся в
начале иерархии классов, приведена на рисунке.10
TObject
TPersistent
TComponent
TPicture
TCanvas
TControl
TGraficControl
TWinControl
Класс TObject является предком всех других классов,
используемых в DELPHI. Он включает в себя характеристики,
свойственные всем используемым классам. Некоторые методы класса
TObject могут использоваться без создания соответствующих объектов с
учетом того, что реального объекта такого класса может и не быть. Эти
методы позволяют получить общие характеристики класса – адрес
таблицы, содержащей характеристики класса, имя класса, имя предка
класса, характеристики методов и т. д. Примеры некоторых методов
класса TObject:

ClassName – функция класса (типа ShortString)
формирует строку, содержащую имя класса, данное ему при создании;

ClassParent
–
функция,
определяющая
класс
непосредственного предка данного класса;

ClassType – функция возвращает класс конкретного
объекта;

InstanceSize – функция (типа Longint) возвращает размер
класса или объекта в байтах;
Всю объектную базу DELPHI можно просмотреть в окне
Browse Objects командой системы программирования View|Browser
после компиляции проекта.
10
39

FieldAddress(Name) – функция типа Pointer возвращает
адрес поля объекта с именем Name типа ShortString.
Класс TPersistent (Постоянный) является потомком класса
TObject и предком всех классов, объекты которых могут быть помещены
в память и взяты из памяти. Основными потомками класса TPersistent
являются классы TComponent (Компонента) – предок всех компонент
проекта; TStrings (Строки) – предок всех списков строк; TCollection
(Коллекция) – коллекция (список) элементов; TGraphicObject
(Графический объект), TCanvas (Канва – основа для рисования), TGraphic
(Графический элемент), TPicture (Изображение) – классы, образующие
так называемый графический инструментарий DELPHI.
Класс TControl является родоначальником всех элементов
управления, с помощью которых выводится информация на экран и с
помощью которых можно вводить информацию в программу, используя
клавиатуру и мышь. Его потомок класс TWinControl служит для создания
окон Windows. Класс TGraphicControl отличается от класса TWinControl
отсутствием у объектов его семейства оконной функции, в связи с чем
такие элементы либо служат для вывода на экран информации, либо
являются чисто декоративными11.
Методы базового класса Tobject, как отмечалось выше,
позволяют легко получать информацию о характеристиках созданного
класса и его потомках.
Задание 2. Подготовить и выполнить программу, выводящую
сообщение о названии типа созданного класса и названии его
непосредственного предка.
Решение задачи выполнить в следующей последовательности:
1.
Открыть новый проект и в качестве заголовка формы
ввести текст “Задание 2”.
2.
На форму поместить две кнопки: “Операция” и
“Закрыть”.
3.
В интерфейсной части модуля после описания класса
TForm1 поместить описание нового класса с именем TNewForm:
TNewForm=class(TForm)
class procedure ClassMessage;
end;
В этом классе введен метод класса ClassMessage (см. п.2.3),
который будет формировать строку с требуемой информацией.
Описание некоторых из упомянутых и других потомков класса
TObject приведено в [1, гл. 13].
11
40
4.
В исполнительной части модуля поместить описание
этого метода:
class procedure TNewForm.ClassMessage;
var s: string;
begin
s:=’Имя
класса:’+ClassName+#13#10’Предок:’+ClassParent.ClassName;
Application.MessageBox(PChar(s),’Информация
о
классе’,MB_OK);
end;
В этом методе формируются две строки: первая
отображает имя класса, для чего используется метод класса
ClassName, определенный в классе TObject, вторая отображает имя
непосредственного предка.
Для вывода имени предка используются два метода класса –
ClassParent и ClassName, определенные в классе TObject. Затем
информация с помощью стандартного метода MessageBox объекта
Application выводится в информационном окне на экран. Это окно имеет
заголовок “Информация о классе” и одну кнопку управления “OK”.
5. В заготовку обработчика событий кнопки “Операция”
поместить оператор обращения к методу класса ClassMessage:
TNewForm.ClassMessage;
Примечание. Метод класса ClassMessage используется в
данном случае, несмотря на то, что ни одного объекта класса
TNewForm не создано (см.п.2.3).
6. Подготовить стандартный обработчик событий для
кнопки “Закрыть”.
7. Выполнить сохранение файлов проекта и модуля в
текущем каталоге, провести компиляцию и запуск программы на
выполнение.
Нажать кнопку “Операция”. На экран должно быть выведено
окно с информацией о типе класса и его предка.
8. Завершить работу программы нажатием кнопки
“Закрыть”.
В Object Pascal можно задавать указатель на класс, называемый
метаклассом. Для этого в объявлении записываются ключевые слова class
of, после чего указывается имя класса, ссылка на который формируется:
type
<имя типа>=class of <базовый класс>;
Примером может быть следующее описание:
type
41
TControlClass= class of TControl;
Этот тип является стандартным в DELPHI и именно так он
определяется в модуле Controls. Введя такой тип данных, далее можно
задавать переменные этого типа, например:
var ControlClass: TControlClass;
Значениями такой переменной могут быть классы, входящие в
семейство исходного класса TControl: сам класс TControl, класс TForm,
класс TButton и т. д. Таким образом, метакласс может быть указателем на
любой класс, входящий в семейство исходного класса.
Введение метаклассов удобно для создания универсальных
подпрограмм, которые могут работать с объектами из целого семейства
классов, причем заранее неизвестно, какой из этих объектов будет
использоваться. В ряде случаев это существенно упрощает создаваемую
программу.
Задание 3. Подготовить и выполнить программу, выводящую
сообщение о характеристиках любого класса – название его типа и
название типа его непосредственного предка.
Решение задачи выполнить в следующей последовательности:
1.
Открыть новый проект и в качестве заголовка формы
ввести текст “Задание 3”.
2.
На форму поместить три кнопки: “Операция1”,
“Операция2” и “Закрыть”. С помощью первых двух кнопок будет
получаться информация о форме и помещенной на ней кнопке.
3.
В интерфейсной части модуля после описания класса
TForm1 поместить описание нового класса с именем TNew2Form:
TNew2Form=class(TForm)
class procedure ClassMessage(TypeClass:TCass);
end;
В этом классе введен метод класса ClassMessage (см. п.2.3),
который будет формировать строку с требуемой информацией.
4.
В исполнительной части модуля поместить описание
этого метода:
class procedure TNew2Form.ClassMessage(TypeClass:TCass);
var s: string;
begin
s:=’Имя класса:’+ TypeClass.ClassName+#13#10’Предок:’+
TypeClass.ClassParent.ClassName;
Application.MessageBox(PChar(s),’Информация
о
классе’,MB_OK);
end;
42
В отличие от метода класса ClassMessage предыдущего
задания в данном случае этому методу передается параметр-метакласс
TypeClass, для которого и определяются имя класса и имя его
непосредственного предка. При обращении к этому методу в качестве
входного параметра можно использовать любой класс, и именно для него
будет получена необходимая информация.
5. Для кнопки “Операция1” создать обработчик события,
поместив в его тело следующий оператор:
TNew2Form.ClassMessage(Form1.ClassType);
Этот оператор вызывает метод класса ClassMessage, и ему
передается тип формы Form1, который получается для объекта Form1
с помощью метода класса ClassType, определенного в классе TObject.
6. Для кнопки “Операция2” создать обработчик события,
поместив в его тело следующий оператор:
TNew2Form.ClassMessage(Form1.Button1.ClassType);
Этот оператор передает методу класса ClassMessage тип
кнопки, для которого и получается необходимая информация.
7.
Подготовить стандартный обработчик событий для
кнопки “Закрыть”.
8.
Выполнить сохранение файлов проекта и модуля в
текущем каталоге, провести компиляцию и запуск программы на
выполнение.
9.
Последовательно
нажать
кнопки
“Операция1”,
“Операция2”. При этом на экран должны быть выведены два окна с
информацией о типе класса и его предка – либо формы, либо кнопки.
10.
Завершить работу программы нажатием кнопки
“Закрыть”.
Задание 4. Дополнить программу задания 1 описаниями класса
TNew2Form и метода ClassMessage из программы задания 3. Поместить
на форму программы задания 1 кнопки “Операция1” и “Операция2” и с
помощью
соответствующих
обработчиков
(по
аналогии
с
обработчиком кнопки “Операция2” в задании 3) получить информацию о
классах TStud и TProf.
Задание 5. Подготовить и выполнить программу построения
графика функции Y=F(X), которая задается следующим образом:
0 <= X < 50
Y = 0,
50 <= X < 100
Y = X - 50,
100 <= X < 150
Y = 50,
150 <= X < 200
Y = -(X - 200),
200 <= X < 250
Y = 0.
Все размеры заданы в пикселах.
Решение задачи выполнить в следующей последовательности:
43
1.
Открыть новый проект и в качестве заголовка формы
ввести текст “Задание 4”.
2.
На форму поместить кнопки: “Операция”, “Закрыть”,
и компоненту Image (Изображение) для размещения на ней графика.
Задать ширину компоненты в 300 пикселов, а высоту – в 150 пикселов.
Выровнять компоненту относительно центральной вертикальной оси.
3.
Для кнопки “Операция” подготовить текст программы
обработчика, рисующего заданный график с использованием свойств и
методов графических инструментов DELPHI, в частности объектов
класса TCanvas Pen (перо), PenPos и методов LineTo и MoveTo12.
4.
Выполнить сохранение файлов проекта и модуля в
текущем каталоге, провести компиляцию и запуск программы на
выполнение.
5.
Завершить работу программы нажатием кнопки
“Закрыть”.
4. Отчет по лабораторной работе
Отчет должен быть оформлен в соответствии с требованиями,
что в лабораторной работе № 1.
Литература
1. Фаронов В.В. Delphi 3.Учебный курс. – М.: “Нолидж”, 1998.
12
Описание этих свойств и методов см. в [1, с. 245-247].
44
Объектно-ориентированное программирование
Методические указания к лабораторным работам
Часть 1
Составил З а с о р и н Сергей Валентинович
Редактор Р. К. Мангутова
Корректор С. В. Макушина
Подписано в печать
Формат бумаги 60х84 1/16
Бумага газетная. Печать трафаретная. Усл. печ. л. 2,75
Уч.-изд.л. 2,75. Тираж 40 экз. Заказ
Рязанский государственный радиотехнический университет
391000, Рязань, ул. Гагарина, 59/1
Редакционно-издательский центр РГРТА
Download