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