- •Предисловие
- •Основы программирования
- •Понятие алгоритма.
- •Алгоритм Евклида.
- •Задача о поездах и мухе
- •Вместо лирического отступления
- •Этапы подготовки задачи для решения на компьютере
- •Примеры разработки алгоритмов
- •Решение квадратного уравнения.
- •Вычисление интегралов
- •Обработка результатов эксперимента
- •Решение системы линейных алгебраических уравнений
- •Введение в язык программирования Pascal
- •Основные элементы языка
- •Переменные. Стандартные типы.
- •Операции отношения
- •Раздел описаний переменных
- •Выражения. Порядок выполнения операций.
- •Константы
- •Комментарии в программе
- •Операторы
- •2.1.7.1. Оператор присваивания
- •2.1.7.2. Операторы ввода/вывода
- •2.1.7.3. Операторы инкремента и декремента
- •Среда разработки Lazarus
- •Русский язык в консольных приложениях
- •Первая программа
- •Открытие существующего проекта
- •Другие способы создания консольных приложений
- •Типовой пустой проект
- •Операции с целыми числами
- •Вместо лирического отступления 2
- •Стандартные функции с целыми аргументами
- •Операции с вещественными числами (тип real).
- •Форматирование вывода
- •Одновременное использование вещественных и целых чисел.
- •Другие стандартные функции с вещественными аргументами
- •Булевы переменные
- •Условные операторы.
- •2.1.22.1 Оператор if …. then
- •2.1.22.2. Оператор if …then ... else
- •Операторы цикла
- •2.1.23.1. Оператор цикла с предусловием
- •2.1.23.2. Оператор цикла с постусловием
- •2.1.23.3. Оператор цикла с параметром.
- •2.1.23.4. Второй вариант оператора цикла с параметром
- •Оператор выбора case
- •Организация простейшего контроля ввода данных.
- •Вычисление сумм сходящихся рядов
- •Реализация некоторых алгоритмов главы 1.
- •Программа решения задачи о поездах и мухе
- •Программа вычисления определенного интеграла
- •Более сложные элементы языка
- •Общая структура Паскаль – программы
- •Процедуры и функции
- •3.1.1.1 Структура процедуры
- •3.1.1.2. Структура функции
- •3.1.1.3 Глобальные и локальные переменные
- •3.1.1.4 Способы передачи параметров
- •3.1.1.5 Процедуры завершения
- •Еще раз о типах данных
- •Классификация типов данных
- •3.2.1.1 Целый тип
- •3.2.1.2. Интервальный тип
- •3.2.1.3. Перечислимый тип
- •3.2.1.4. Множества
- •3.2.1.5. Логический тип
- •3.2.1.6. Вещественный тип
- •3.2.1.7. Указатели
- •Обработка символьной информации в Паскале
- •Символьные и строковые типы данных.
- •3.3.1.1. Тип Char
- •3.3.1.2. Функции для работы с символами
- •3.3.1.3. Тип String
- •3.3.1.4. Строковые процедуры и функции
- •Массивы
- •Динамические массивы
- •Программа решения системы линейных алгебраических уравнений методом Гаусса
- •3.4.1.1. Вариант 1 – с goto
- •3.4.1.2. Вариант 2 – без goto
- •3.4.1.3. Вариант 3 – наилучшая реализация
- •Модули в Паскале
- •Структура модуля
- •Системные модули
- •3.5.2.1. Модуль CRT
- •Файлы
- •Тип данных – запись
- •Файловые типы
- •Процедуры для работы с файлами
- •3.6.3.1. Общие процедуры для работы с файлами всех типов
- •3.6.3.2. Процедуры для работы с текстовыми файлами
- •3.6.3.3. Процедуры для работы с типизированными файлами
- •3.6.3.4. Процедуры для работы с нетипизированными файлами
- •3.6.3.5. Организация контроля ввода/вывода при работе файлами
- •3.6.3.6. Создание простой базы данных с типизированными файлами.
- •Алгоритмы сортировки
- •Обменная сортировка (метод "пузырька")
- •Сортировка выбором
- •Сортировка вставками
- •Метод быстрой сортировки
- •Алгоритмы поиска
- •Поиск в массивах
- •Вставка и удаление элементов в упорядоченном массиве
- •Динамические структуры данных
- •Представление в памяти компьютера динамических структур.
- •Реализация стека с помощью массивов
- •Указатели
- •Стандартные операции с линейными списками
- •Реализация динамических структур линейными списками
- •4.3.6.1. Реализация стека
- •4.3.6.2. Реализация очереди с помощью линейного списка
- •4.3.6.3. Реализация двоичного дерева с помощью линейного списка
- •Сортировка и поиск с помощью двоичного дерева
- •Три источника и три составные части ООП.
- •Классы и объекты.
- •Обращение к членам класса.
- •Инкапсуляция
- •Спецификаторы доступа.
- •Свойства.
- •Наследование
- •Полиморфизм
- •Раннее связывание.
- •Позднее связывание.
- •Конструкторы и деструкторы.
- •Элементы графического интерфейса
- •Различия между консольными и графическими приложениями
- •Визуальное программирование в среде Lazarus
- •Создание графического приложения
- •Форма и ее основные свойства
- •Компоненты
- •Обработчики событий
- •Простейшие компоненты
- •6.3.5.1. Компонент TLabel
- •6.3.5.2. Кнопки TButton, TBitBtn и TSpeedButton
- •6.3.6.1. Компонент TEdit
- •6.3.6.2. Компонент TLabeledEdit
- •6.3.7.1. Компонент TMaskEdit
- •Специальные компоненты для ввода чисел
- •Тестирование и отладка программы
- •Компоненты отображения и выбора данных
- •6.3.10.1. Компонент TMemo
- •6.3.10.2. Компонент TStringGrid
- •6.3.10.3. Компоненты выбора
- •Компонент TListBox
- •Компонент TComboBox
- •Компоненты выбора – переключатели
- •6.3.10.4. Компоненты отображения структурированных данных
- •Компонент TTreeView
- •Компонент TListView
- •Организация меню. Механизм действий - Actions
- •6.3.11.1. Компонент TMainMenu
- •6.3.11.2. Компонент TToolBar
- •6.3.11.3. Компонент TActionList
- •6.3.11.4. Создание приложений с изменяемыми размерами окон
- •Послесловие
- •Литература
- •Алфавитный указатель
Глава 5 Основы объектно-ориентированного программирования
____________________________________________________________________
procedure SetData(const f_name, s_name: string);
и нажмите Ctrl+Shift+C. Lazarus автоматически создаст следующий код:
procedure THuman.SetData(const f_name, s_name: string); begin
end;
5.3.2Свойства.
Впредыдущей программе для доступа к частным (private) полям мы использовали методы, которые поместили в раздел public. Фактически мы организовали обмен данными между классом и внешней средой. Но для досту-
па к полям данных в классе лучше использовать свойства. Свойства описывают состояние объекта, поскольку определяются полями класса и снабжены двумя специальными методами для записи и чтения значения поля. Таким образом,
свойство это специальный механизм для организации доступа к полю. Опреде-
ляется тремя составляющими: поле, метод чтения, метод записи. Преимущество свойства в том, что методы чтения и записи полностью скрыты. Это позволяет вносить изменения в код класса не изменяя использующий его внешний код.
Объявление свойства имеет вид:
property имя 1: тип <read имя 2> <write имя 3>;
где property (свойство) – ключевое слово;
имя 1 – имя свойства, любой разрешенный идентификатор ;
тип – тип поля;
имя 2 – имя метода чтения или непосредственно имя поля;
имя 3 – имя метода записи или непосредственно имя поля;
417
5.3 Инкапсуляция
____________________________________________________________________
Угловые скобки означают, что данный параметр может отсутствовать. В случае отсутствия параметра write свойство становится свойством "только для чте-
ния". Изменить значение свойства тогда будет невозможно. Отсутствие пара-
метра read приводит к тому, что свойство становится свойством "только для записи". Однако это лишено смысла, поскольку значение этого свойства (для чтения) будет недоступно.
Наиболее логично использовать свойство со следующими параметрами:
property имя свойства: тип read имя поля write имя метода записи;
В этом случае для обращения к значению свойства программа производит чтение непосредственно защищенного поля, а для записи значения свойства будет вызываться метод записи. В методе перед записью можно организовать контроль данных на соответствие каким-либо критериям в зависимости от ре-
шаемой задачи.
Объявления свойств следует располагать в разделе public. При записи свойства вы также можете воспользоваться функцией "Автозавершение кода"
редактора исходного кода. Введите
property имя свойства: тип
и нажмите Ctrl+Shift+C. Lazarus автоматически завершит объявление свой-
ства, а также заготовку тела метода записи. Кроме того, добавит в секцию private поле с именем <Fимя свойства> с соответствующим типом и проце-
дуру записи со стандартным именем <Setимя свойства>. Имена полей принято начинать с буквы F, поэтому Lazarus формирует такое имя. Но это не обяза-
тельно. Если вас не устраивают имена, предложенные Lazarus, вы можете про-
сто их переименовать. Например, начните набирать описание класса:
418
Глава 5 Основы объектно-ориентированного программирования
____________________________________________________________________
type
THuman = class
private
name: string;
public
property name: string
end;
Нажмите Ctrl+Shift+C. Автоматически будет создан следующий код:
type
{THuman }
THuman = class private
Fname: string; name: string;
procedure Setname(const AValue: string); public
property name: string read Fname write Setname; end;
implementation
procedure THuman.Setname(const AValue: string);
begin
if Fname=AValue then exit;
Fname:= AValue;
419
5.3 Инкапсуляция
____________________________________________________________________
end;
Поскольку при использовании функции "Автозавершение кода" Lazarus
всегда добавляет новое поле в секцию private, логичнее начинать описание класса со спецификатора public и определения свойств. В этом случае секция private также будет автоматически создана и вы получите описание полей и свойств и готовые шаблоны реализации методов записи. В данном случае мы получили описание поля Fname и заготовку процедуры Setname.
При использовании свойства нет необходимости явно вызывать процедуру записи. Достаточно записать:
Person:= THuman.Create;
Person.name:= AValue;
Таким образом, для пользователя класса свойство будет выглядеть как обычное поле.
Если вы хотите (при использовании функции "Автозавершение кода") для чтения также использовать метод, то вам достаточно перед именем поля в опи-
сании свойства добавить слово Get и вновь нажать на комбинацию клавиш
Ctrl+Shift+C. Вы получите заготовку процедуры чтения, например:
property name: string read GetFname write Setname;
…………………………………………………………………………………………………………………………………
implementation
function THuman.GetFname: string; begin
end;
Рассмотрим примеры работы со свойствами.
420
Глава 5 Основы объектно-ориентированного программирования
____________________________________________________________________
unit Unit1;
{$mode objfpc}{$H+} interface
uses
Classes, SysUtils; type
{ THuman } THuman = class
private
Fname: string;
Ffam: string;
procedure Setfam(const AValue: string); procedure Setname(const AValue: string);
public
property name: string read Fname write Setname; property fam: string read Ffam write Setfam; function GetData: string;
end;
implementation { THuman }
procedure THuman.Setname(const AValue: string); begin
if Fname = AValue then exit; Fname:= AValue;
end;
procedure THuman.Setfam(const AValue: string); begin
if Ffam = AValue then exit;
421
5.3 Инкапсуляция
____________________________________________________________________
Ffam:= AValue; end;
function THuman.GetData: string; begin
Result:= name + ' ' + fam; end;
end.
program project1; {$mode objfpc}{$H+} uses
CRT, FileUtil, Unit1; var
Person: THuman; fname: string;
begin
Person:= THuman.Create;
Person.name:= 'Виталий';
Person.fam:= 'Петров'; fname:= Person.GetData;
writeln(UTF8ToConsole('Это: ' + fname)); writeln(UTF8ToConsole('Нажмите любую клавишу')); readkey;
Person.Free;
end.
В этой программе мы определили два свойства name и fam. Воспользо-
вавшись функцией автозавершения, мы получили методы записи данных в по-
ля. В программе в явном виде мы эти методы не вызывали. Мы записали про-
422
Глава 5 Основы объектно-ориентированного программирования
____________________________________________________________________
сто
Person.name:= 'Виталий';
Person.fam:= 'Петров';
Всю остальную работу (вызов методов записи) за нас выполнил компиля-
тор. Обратите внимание, по сравнению с предыдущей программой name и fam
это не имена полей, а имена свойств. В следующем примере данные считыва-
ются с клавиатуры. Добавлен контроль ввода данных.
unit Unit1;
{$mode objfpc}{$H+} interface
uses
Classes, SysUtils; type
{ THuman }
THuman = class private
Fname: string;
Ffam: string;
Fbirthday: integer;
procedure Setname(const AValue: string); procedure Setfam(const AValue: string); procedure Setbirthday(const AValue: integer);
public
property name: string read Fname write Setname; property fam: string read Ffam write Setfam;
423
5.3 Инкапсуляция
____________________________________________________________________
property birthday: integer read Fbirthday write Setbirthday;
function GetData: string; end;
implementation
{ THuman }
procedure THuman.Setname(const AValue: string); begin
if Fname = AValue then exit; Fname:= AValue;
end;
procedure THuman.Setfam(const AValue: string); begin
if Ffam = AValue then exit; Ffam:= AValue;
end;
procedure THuman.Setbirthday(const AValue: integer); begin
if Fbirthday = AValue then exit; Fbirthday:= AValue;
end;
function THuman.GetData: string; var
s: string;
424
Глава 5 Основы объектно-ориентированного программирования
____________________________________________________________________
begin str(birthday, s);
Result:= name + ' ' + fam + ' ' + s; end;
end.
program project1;
{$mode objfpc}{$H+}
uses
CRT, FileUtil, Unit1; var
Person: THuman;
fname, sname, s_year: string; code, year: integer;
begin
Person:= THuman.Create; writeln(UTF8ToConsole('Введите имя')); readln(fname);
Person.name:= fname; writeln(UTF8ToConsole('Введите фамилию')); readln(sname);
Person.fam:= sname;
writeln(UTF8ToConsole('Введите год рождения'));
readln(s_year);
val(s_year, |
year, |
code); |
// |
контроль ввода |
425