Object Oriented Programming with Free Pascal and Lazarus/ru: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Object Oriented Programming with Free Pascal and Lazarus/ru
| Old | New | Line | |
|---|---|---|---|
| 1 | + | Существует много отличных учебников по Pascal, но этот служит попыткой вести начинающего программиста далее, в объектно-ориентированное программирование ([[Glossary|Object-Oriented Programming]]) являющееся расширением стандартного Pascal, применяемое в TurboPascal, Delphi и FreePascal/Lazarus. | |
| 2 | + | ||
| 3 | + | [[Glossary|Object]] (Объект) - это расширение стандартной структуры Pascal [record](http://wiki.lazarus.freepascal.org/Record) (Запись). | |
| 4 | + | ||
| 5 | + | Стандартное текстовое программирование на Pascal пригодно для создания приложений, которые, как обычные приложения Unix, очень хорошо выполняют всего одну функцию. Программа может выполнять и очень сложные действия, предлагая пользователю выборы из меню, но по существу ограничена командами, которые пользователь набирает на клавиатуре и смотрит ответы на терминале или принтере. | |
| 6 | + | ||
| 7 | + | Для создания графического интерфейса пользователя [[Glossary|Graphical User Interface (GUI)]] обычно применяются методы объектно-ориентированного программирования (чаще всего на [[Glossary|C]] или его вариантах, или Visual Basic, или на одном из [[Glossary|OO]] вариантов Pascal, таких, как [[Glossary|FreePascal]] совместно с [[Glossary|Lazarus]], или без него). | |
| 8 | + | ||
| 9 | + | На GUI потребителю предоставляется экран с множеством картинок, отображающих определенную структуру, содержащую набор инструментов, или [[Glossary|Widgets]] (Виджетов), ассоциированных с различными действиями, таких как | |
| 10 | + | ||
| 11 | + | - Выбор из меню, | |
| 12 | + | - Открытие или сохранение файлов, | |
| 13 | + | - Соединение с Интернет, | |
| 14 | + | - Выполнение вычислений, и т.п. | |
| 15 | + | ||
| 16 | + | Пользователь перемещает по экрану указатель мыши или иного инструмента выбора точки для выбора действия, выполняемого в ответ на щелчок мыши или нажатие клавиши. | |
| 17 | + | ||
| 18 | + | Программы со сложным графическим интерфейсом могут быть написаны на стандартном Pascal или любом другом языке программирования, но намного проще применить объектно-ориентированную систему, в которой каждый графический объект на экране может иметь собственный набор свойств, процедур и функций, существующих совместно, в общей структуре. | |
| 19 | + | ||
| 20 | + | ## Объекты - аналогия реального мира | |
| 21 | + | ||
| 22 | + | Объекты напоминают результаты анализа крови из больницы или поликлиники. | |
| 23 | + | ||
| 24 | + | ### Анализ крови | |
| 25 | + | ||
| 26 | + | Экземпляр анализа - несомненно, **объект**; он имеет много связанной информации, документов и других физических объектов. | |
| 27 | + | ||
| 28 | + | - **Трубка для анализа**, определенного типа, который заказал врач. | |
| 29 | + | ||
| 30 | + | - **Отдельные правила** (или *методика*, *способ выполнения*) для указания медсестре, берущей анализ. | |
| 31 | + | - какой тип трубки применить, | |
| 32 | + | - как произвести отбор анализа, | |
| 33 | + | - как хранить его до передачи в лабораторию. | |
| 34 | + | ||
| 35 | + | - **Этикетка** на трубке с указанием | |
| 36 | + | - номера анализа | |
| 37 | + | - имени пациента и даты рождения | |
| 38 | + | - даты и времени взятия | |
| 39 | + | - требуемых проверок. | |
| 40 | + | ||
| 41 | + | - **Бланк запроса** для лаборатории, указывающий | |
| 42 | + | - Номер анализа | |
| 43 | + | - Номер запроса врача | |
| 44 | + | - что предусматривает запрос врача и | |
| 45 | + | - дается более полная информация о пациенте | |
| 46 | + | - возможный диагноз, которому нужно подтверждение. | |
| 47 | + | ||
| 48 | + | Копия запроса помещается в карточку пациента для напоминания врачу об ожидании результата в соответствующее время. | |
| 49 | + | ||
| 50 | + | - В лабораторию - **отдельные методы** для указания | |
| 51 | + | - как производить анализ, | |
| 52 | + | - какую применять аппаратуру, | |
| 53 | + | - как откалибровать и произвести замеры на приборе, | |
| 54 | + | - как результаты должны быть отображены и | |
| 55 | + | - направлены врачу. | |
| 56 | + | ||
| 57 | + | Фактически **результаты** - запись, помогающая врачу установить диагноз, и ее копия помещается в карточку пациента. | |
| 58 | + | ||
| 59 | + | Физическая доза крови может быть оставлена на хранение для контроля или дальнейших проверок, может быть слита в раковину, или сожжена; это также должно быть описано. | |
| 60 | + | ||
| 61 | + | Однако в жизни для врача нет необходимости описывать по буквам все детали и инструкции для каждого анализа; действительно, он может иметь немного понятий об обработке анализа в лаборатории. Детали разных процессов **унаследованы** от предшествующих анализов - имеется общий план для всей последовательности - и мы можем представить анализ крови с его документами, данными и основными методами, как комплекс **объект**. | |
| 62 | + | ||
| 63 | + | В уме врача анализ крови выглядит в большей степени, как его результат, для медсестры - как доза крови, трубка, этикетка и условия хранения; а по сути - это единый объект. | |
| 64 | + | ||
| 65 | + | ### Другой пример - автомобиль | |
| 66 | + | ||
| 67 | + | Если Вас пугает пример с кровью, те же рассуждения могут быть приложены к автомобилю, сданному в гараж для ремонта. | |
| 68 | + | ||
| 69 | + | Он может состоять из: | |
| 70 | + | ||
| 71 | + | - физической автомашины | |
| 72 | + | - документов владельца: регистрации или лицензии (включая номерной знак), страхового свидетельства, денег для покупки частей, оплаты ремонта и т.д. | |
| 73 | + | - информации о потреблении топлива | |
| 74 | + | - документов водителей, управлявших машиной, с их частными лицензиями | |
| 75 | + | - записей об обслуживании, хранящихся в гараже | |
| 76 | + | - описаний способов или процедур для обычной проверки и эксплуатации | |
| 77 | + | - способов более сложного ремонта и т.д. | |
| 78 | + | - выписанного счета для клиента | |
| 79 | + | ||
| 80 | + | ## Пример программирования | |
| 81 | + | ||
| 82 | + | Достаточно этих введений с примерами из реального мира! Обратимся к основной цели - программированию на FreePascal. | |
| 83 | + | ||
| 84 | + | Рассмотрим создание простой формы с несколькими элементами управления для приложения на FreePascal/Lazarus. | |
| 85 | + | ||
| 86 | + | <div class="floatleft"> | |
| 87 | + | ||
| 88 | + | <figure> | |
| 89 | + | <img src="ObjectInspector-TForm.png" title="ObjectInspector-TForm.png" /> | |
| 90 | + | <figcaption>ObjectInspector-TForm.png</figcaption> | |
| 91 | + | </figure> | |
| 92 | + | ||
| 93 | + | </div> | |
| 94 | + | ||
| 95 | + | <div class="floatright"> | |
| 96 | + | ||
| 97 | + | <figure> | |
| 98 | + | <img src="BlankForm.png" title="BlankForm.png" /> | |
| 99 | + | <figcaption>BlankForm.png</figcaption> | |
| 100 | + | </figure> | |
| 101 | + | ||
| 102 | + | </div> | |
| 103 | + | ||
| 104 | + | Вначале Lazarus IDE представляет программисту шаблон пустой формы, на которой можно размещать различные элементы управления, или объекты. | |
| 105 | + | ||
| 106 | + | Предоставленный бланк уже является объектом, со своими свойствами, такими как Позиция (Верх и Отступ), размер (Высота и Ширина), цвет, шрифт для текста и т.д. | |
| 107 | + | ||
| 108 | + | ------------------------------------------------------------------------ | |
| 109 | + | ||
| 110 | + | Если на форму поместить кнопку (тип TButton), она будет иметь свой набор свойств, который можно просмотреть в окне Инспектора Объектов. | |
| 111 | + | ||
| 112 | + | Некоторые свойства кнопки имеют те же имена, что и свойства формы, что является следствием **Наследования** многих свойств из общего класса - предка, указывающего, как свойства определяются и управляются в классе - потомке. | |
| 113 | + | ||
| 114 | + | Как и для свойств, Инспектор Объектов имеет вкладку, называемую **События**, дающую возможность настроить реакцию объекта на внешние воздействия, такие как щелчок мыши на кнопке (OnClick), или некоторое изменение позиции, размера, или других свойств (OnChange), для того, чтобы приложение выполняло в ответ некоторые действия. | |
| 115 | + | ||
| 116 | + | Физический образ кнопки на форме, совместно с его свойствами и методами обработки событий считается единой сущностью, или **Объектом** в Pascal. | |
| 117 | + | ||
| 118 | + | <div class="floatleft"> | |
| 119 | + | ||
| 120 | + | <figure> | |
| 121 | + | <img src="ObjectInspector-TButton.png" title="ObjectInspector-TButton.png" /> | |
| 122 | + | <figcaption>ObjectInspector-TButton.png</figcaption> | |
| 123 | + | </figure> | |
| 124 | + | ||
| 125 | + | </div> | |
| 126 | + | ||
| 127 | + | <div class="floatcenter"> | |
| 128 | + | ||
| 129 | + | <figure> | |
| 130 | + | <img src="FormWithButton.png" title="FormWithButton.png" /> | |
| 131 | + | <figcaption>FormWithButton.png</figcaption> | |
| 132 | + | </figure> | |
| 133 | + | ||
| 134 | + | </div> | |
| 135 | + | ||
| 136 | + | <div class="floatright"> | |
| 137 | + | ||
| 138 | + | <figure> | |
| 139 | + | <img src="Source_FormWithButton1.png" title="Source_FormWithButton1.png" /> | |
| 140 | + | <figcaption>Source_FormWithButton1.png</figcaption> | |
| 141 | + | </figure> | |
| 142 | + | ||
| 143 | + | </div> | |
| 144 | + | ||
| 145 | + | ## Объектно-ориентированное расширение стандартного Pascal | |
| 146 | + | ||
| 147 | + | Структура Pascal "Запись" расширена определением | |
| 148 | + | ||
| 149 | + | ### Объект | |
| 150 | + | ||
| 151 | + | Объект - это специальный тип записи. Запись объекта содержит все поля, объявленные в определении объекта (как и в обычной записи), но в дополнение могут быть объявлены процедуры и функции, как неотъемлемые части этой записи, указывающие на методы, ассоциированные с типом объекта. | |
| 152 | + | ||
| 153 | + | Например, объект содержит массив вещественных значений, совместно с Методом для вычисления среднего арифметического. | |
| 154 | + | ||
| 155 | + | `Type`\ | |
| 156 | + | ` Average = Object`\ | |
| 157 | + | ` NumVal: Integer;`\ | |
| 158 | + | ` Values: Array [1..200] of Real;`\ | |
| 159 | + | ` Function Mean: Real; { calculates the average value of the array }`\ | |
| 160 | + | ` End;` | |
| 161 | + | ||
| 162 | + | Объекты могут ”наследовать” поля и методы от ”родительских” объектов. Этим подразумевается, что эти поля и методы могут применяться и в объекте, объявленном ”потомком”. | |
| 163 | + | ||
| 164 | + | Кроме того, введено понятие видимости: поля, процедуры и функции могут объявляться публичными, защищенными и частными. По умолчанию, поля и методы - публичные, и могут экспортироваться из текущего модуля. Защищенные поля или методы пригодны только для непосредственных потомков текущего родительского объекта. Частные поля или методы доступны только в текущем модуле: их область действия ограничена текущим модулем. | |
| 165 | + | ||
| 166 | + | ### Класс | |
| 167 | + | ||
| 168 | + | Объекты применяются самостоятельно во FreePascal и Lazarus не очень часто; однако классы получили широкое применение. Класс определяется почти так же, как объект, но является не самим объектом, а указателем на него. Технически это означает, что Класс располагается в теле программы, тогда как Объект располагается в стеке. | |
| 169 | + | ||
| 170 | + | Приведем пример обычного объявления Класса: | |
| 171 | + | ||
| 172 | + | `{-----------------------------------------}`\ | |
| 173 | + | `{example of Class declaration from the LCL}`\ | |
| 174 | + | `{-----------------------------------------}`\ | |
| 175 | + | ` TPen = class(TFPCustomPen)`\ | |
| 176 | + | ` private`\ | |
| 177 | + | ` FColor: TColor;`\ | |
| 178 | + | ` FPenHandleCached: boolean;`\ | |
| 179 | + | ` FReference: TWSPenReference;`\ | |
| 180 | + | ` procedure FreeReference;`\ | |
| 181 | + | ` function GetHandle: HPEN;`\ | |
| 182 | + | ` function GetReference: TWSPenReference;`\ | |
| 183 | + | ` procedure ReferenceNeeded;`\ | |
| 184 | + | ` procedure SetHandle(const Value: HPEN);`\ | |
| 185 | + | ` protected`\ | |
| 186 | + | ` procedure DoAllocateResources; override;`\ | |
| 187 | + | ` procedure DoDeAllocateResources; override;`\ | |
| 188 | + | ` procedure DoCopyProps(From: TFPCanvasHelper); override;`\ | |
| 189 | + | ` procedure SetColor`\ | |
| 190 | + | ` (const NewColor: TColor; const NewFPColor: TFPColor); virtual;`\ | |
| 191 | + | ` procedure SetFPColor(const AValue: TFPColor); override;`\ | |
| 192 | + | ` procedure SetColor(Value: TColor);`\ | |
| 193 | + | ` procedure SetMode(Value: TPenMode); override;`\ | |
| 194 | + | ` procedure SetStyle(Value: TPenStyle); override;`\ | |
| 195 | + | ` procedure SetWidth(value: Integer); override;`\ | |
| 196 | + | ` public`\ | |
| 197 | + | ` constructor Create; override;`\ | |
| 198 | + | ` destructor Destroy; override;`\ | |
| 199 | + | ` procedure Assign(Source: TPersistent); override;`\ | |
| 200 | + | ` property Handle: HPEN read GetHandle write SetHandle; deprecated;`\ | |
| 201 | + | ` property Reference: TWSPenReference read GetReference;`\ | |
| 202 | + | ` published`\ | |
| 203 | + | ` property Color: TColor read FColor write SetColor default clBlack;`\ | |
| 204 | + | ` property Mode default pmCopy;`\ | |
| 205 | + | ` property Style default psSolid;`\ | |
| 206 | + | ` property Width default 1;`\ | |
| 207 | + | ` end;` | |
| 208 | + | ||
| 209 | + | Этот класс определен как экземпляр другого **родительского** или класса **предка** (*TFPCustomPen*) от которого он **наследует** все его свойства и методы. Он имеет собственные поля, сгруппированные как | |
| 210 | + | ||
| 211 | + | - **private(частные)** - это означает, что элементы, определенные здесь, доступны или видимы другим классам или процедурам/функциям, определенным только внутри данного программного модуля (Этот пример - из *Graphics*, так что любой из других классов -*TBitMap*, *TPicture* и т.д. этого же модуля может их использовать). Это как локальные переменные (напр. *FColor*, *FPenHandleCached*) или локально используемые методы (*GetHandle*, *SetHandle*), но можно использовать или ссылаться на элементы, объявленные в секциях **protected** или **public**. | |
| 212 | + | - **protected(защищенные)** - это означает, что элементы, определенные здесь, доступны или видимы только классам, произведенным из этого класса - **предка**, и унаследовали его свойства и методы. | |
| 213 | + | - **public** - это означает, что элементы, определенные здесь, доступны любому программному модулю, включившему текущий модуль в свою секцию [[Glossary|Uses]] | |
| 214 | + | - **published** - подобна секции **public**, но компилятор генерирует типовую информацию, требуемую для автоматического подключения этих классов. Часто список published элементов появляется Инспекторе объектов Lazarus; если список **published** отсутствует, в Инспекторе объектов обычно появляются поля **public**. | |
| 215 | + | ||
| 216 | + | ### Методы | |
| 217 | + | ||
| 218 | + | Метод подобен обычной процедуре или функции, но может иметь некие дополнительные **директивы**. | |
| 219 | + | ||
| 220 | + | Некоторые методы, определенные выше, помечены директивой **virtual (виртуальный)**; другие - **override (аннулируемый)**. | |
| 221 | + | ||
| 222 | + | - **virtual** означает, что тип, или фактический экземпляр метода не известен во время компиляции, но выбирается во время выполнения в зависимости от того, какая подпрограмма вызывает метод. Он может рассматриваться как заполнитель в определении класса. | |
| 223 | + | - **override** означает, что во время выполнения локально данное определение может заменить определение, унаследованное от класса - предка, особенно, если оно было **virtual**. Если необходимо применить метод, определенный в родительском классе, его нужно вызывать специфично, с оговоркой **inherited**. | |
| 224 | + | ||
| 225 | + | Методы без директив virtual или override являются **статическими** (обычными для Pascal). Методы, имеющие такие директивы, считаются **динамическими**. | |
| 226 | + | ||
| 227 | + | Методы имеют специальные возможности: | |
| 228 | + | ||
| 229 | + | - **create** - **constructor** для класса, заботящегося о распределении памяти, сбора всей необходимой информации и настройки/инициализации различных свойств. | |
| 230 | + | - **destroy** - **destructor** для класса, упорядоченно удаляющего все составляющие класса из системы, и возвращающего все свои ресурсы системе для повторного использования. | |
| 231 | + | ||
| 232 | + | ### Свойства | |
| 233 | + | ||
| 234 | + | Свойства аналогичны простым полям в "Записи" стандартного Pascal, но могут иметь указатели **чтение** и/или **запись**. | |
| 235 | + | ||
| 236 | + | - Указатель **чтение** является полем или функцией, возвращающим результат корректного типа для свойства. В вышеприведенном примере, свойство *Color* имеет указатель чтения *FColor*, являющийся локальной переменной, которая содержит используемое значение. Если свойство имеет указатель **read** и не имеет **write**, оно служит только для чтения. | |
| 237 | + | - Указатель **запись** является полем или процедурой, устанавливающей значение свойства в определенное место. В вышеприведенном примере, *Color* имеет указатель записи *SetColor*, являющийся процедурой (определено в секции **protected**) для записи значения цвета в указанное место. Если свойство имеет указатель **write** и не имеет **read**, оно служит только для записи. | |
| 238 | + | - **default** - имеется возможность установки значения свойства по умолчанию **default**. Например, *Color* имеет значение по умолчанию *clBlack*, или черный, во время создания. Впоследствии ему можно присвоить другое значение оператором присвоения в программе или через Инспектор объектов. | |
| 239 | + | ||
| 240 | + | ## Дальнейшая информация | |
| 241 | + | ||
| 242 | + | Здесь даны только самые начала темы. Для дальнейшего изучения настоятельно рекомендуется читать руководство [FreePascal](http://lazarus-ccr.sourceforge.net/fpcdoc/ref/ref.html), в особенности главы 5 (**Объекты**) и 6 (**Классы**) | |
| 243 | + | ||
| 244 | + | --Kirkpatc 11:04, 20 July 2008 (CEST) | |
| 245 | + | ||
| 246 | + | ------------------------------------------------------------------------ | |
| 247 | + | ||
| 248 | + | [[Console Mode Pascal/ru]] | |
| 249 | + | ||
| 250 | + | --- | |
| 251 | + | *From the Free Pascal wiki, page "Object Oriented Programming with Free Pascal and Lazarus/ru", as it stood on 2015-06-19 after a change by FTurtle, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
