Object Oriented Programming with Free Pascal and Lazarus/ru: what changed
Revision 2 to 3. 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 | 86 |  | |
| 87 | 87 | ||
| 88 | 88 |  | |
| 89 | 89 | ||
| 90 | 90 | Вначале Lazarus IDE представляет программисту шаблон пустой формы, на которой можно размещать различные элементы управления, или объекты. | |
| 91 | 91 | ||
| 92 | 92 | Предоставленный бланк уже является объектом, со своими свойствами, такими как Позиция (Верх и Отступ), размер (Высота и Ширина), цвет, шрифт для текста и т.д. | |
| 93 | 93 | ||
| 94 | 94 | ------------------------------------------------------------------------ | |
| 95 | 95 | ||
| 96 | 96 | Если на форму поместить кнопку (тип TButton), она будет иметь свой набор свойств, который можно просмотреть в окне Инспектора Объектов. | |
| 97 | 97 | ||
| 98 | 98 | Некоторые свойства кнопки имеют те же имена, что и свойства формы, что является следствием **Наследования** многих свойств из общего класса - предка, указывающего, как свойства определяются и управляются в классе - потомке. | |
| 99 | 99 | ||
| 100 | 100 | Как и для свойств, Инспектор Объектов имеет вкладку, называемую **События**, дающую возможность настроить реакцию объекта на внешние воздействия, такие как щелчок мыши на кнопке (OnClick), или некоторое изменение позиции, размера, или других свойств (OnChange), для того, чтобы приложение выполняло в ответ некоторые действия. | |
| 101 | 101 | ||
| 102 | 102 | Физический образ кнопки на форме, совместно с его свойствами и методами обработки событий считается единой сущностью, или **Объектом** в Pascal. | |
| 103 | 103 | ||
| 104 | 104 |  | |
| 105 | 105 | ||
| 106 | 106 |  | |
| 107 | 107 | ||
| 108 | 108 |  | |
| 109 | 109 | ||
| 110 | 110 | ## Объектно-ориентированное расширение стандартного Pascal | |
| 111 | 111 | ||
| 112 | 112 | Структура Pascal "Запись" расширена определением | |
| 113 | 113 | ||
| 114 | 114 | ### Объект | |
| 115 | 115 | ||
| 116 | 116 | Объект - это специальный тип записи. Запись объекта содержит все поля, объявленные в определении объекта (как и в обычной записи), но в дополнение могут быть объявлены процедуры и функции, как неотъемлемые части этой записи, указывающие на методы, ассоциированные с типом объекта. | |
| 117 | 117 | ||
| 118 | 118 | Например, объект содержит массив вещественных значений, совместно с Методом для вычисления среднего арифметического. | |
| 119 | 119 | ||
| 120 | - | ||
| 121 | - | ||
| 122 | - | ||
| 123 | - | ||
| 124 | - | ||
| 125 | - | ||
| 120 | + | ``` pascal | |
| 121 | + | Type | |
| 122 | + | Average = Object | |
| 123 | + | NumVal: Integer; | |
| 124 | + | Values: Array [1..200] of Real; | |
| 125 | + | Function Mean: Real; { calculates the average value of the array } | |
| 126 | + | End; | |
| 127 | + | ``` | |
| 126 | 128 | ||
| 127 | 129 | Объекты могут ”наследовать” поля и методы от ”родительских” объектов. Этим подразумевается, что эти поля и методы могут применяться и в объекте, объявленном ”потомком”. | |
| 128 | 130 | ||
| 129 | 131 | Кроме того, введено понятие видимости: поля, процедуры и функции могут объявляться публичными, защищенными и частными. По умолчанию, поля и методы - публичные, и могут экспортироваться из текущего модуля. Защищенные поля или методы пригодны только для непосредственных потомков текущего родительского объекта. Частные поля или методы доступны только в текущем модуле: их область действия ограничена текущим модулем. | |
| 130 | 132 | ||
| 131 | 133 | ### Класс | |
| 132 | 134 | ||
| 133 | 135 | Объекты применяются самостоятельно во FreePascal и Lazarus не очень часто; однако классы получили широкое применение. Класс определяется почти так же, как объект, но является не самим объектом, а указателем на него. Технически это означает, что Класс располагается в теле программы, тогда как Объект располагается в стеке. | |
| 134 | 136 | ||
| 135 | 137 | Приведем пример обычного объявления Класса: | |
| 136 | 138 | ||
| 137 | - | ||
| 138 | - | ||
| 139 | - | ||
| 140 | - | ||
| 141 | - | ||
| 142 | - | ||
| 143 | - | ||
| 144 | - | ||
| 145 | - | ||
| 146 | - | ||
| 147 | - | ||
| 148 | - | ||
| 149 | - | ||
| 150 | - | ||
| 151 | - | ||
| 152 | - | ||
| 153 | - | ||
| 154 | - | ||
| 155 | - | ||
| 156 | - | ||
| 157 | - | ||
| 158 | - | ||
| 159 | - | ||
| 160 | - | ||
| 161 | - | ||
| 162 | - | ||
| 163 | - | ||
| 164 | - | ||
| 165 | - | ||
| 166 | - | ||
| 167 | - | ||
| 168 | - | ||
| 169 | - | ||
| 170 | - | ||
| 171 | - | ||
| 172 | - | ||
| 139 | + | ``` pascal | |
| 140 | + | {-----------------------------------------} | |
| 141 | + | {example of Class declaration from the LCL} | |
| 142 | + | {-----------------------------------------} | |
| 143 | + | TPen = class(TFPCustomPen) | |
| 144 | + | private | |
| 145 | + | FColor: TColor; | |
| 146 | + | FPenHandleCached: boolean; | |
| 147 | + | FReference: TWSPenReference; | |
| 148 | + | procedure FreeReference; | |
| 149 | + | function GetHandle: HPEN; | |
| 150 | + | function GetReference: TWSPenReference; | |
| 151 | + | procedure ReferenceNeeded; | |
| 152 | + | procedure SetHandle(const Value: HPEN); | |
| 153 | + | protected | |
| 154 | + | procedure DoAllocateResources; override; | |
| 155 | + | procedure DoDeAllocateResources; override; | |
| 156 | + | procedure DoCopyProps(From: TFPCanvasHelper); override; | |
| 157 | + | procedure SetColor | |
| 158 | + | (const NewColor: TColor; const NewFPColor: TFPColor); virtual; | |
| 159 | + | procedure SetFPColor(const AValue: TFPColor); override; | |
| 160 | + | procedure SetColor(Value: TColor); | |
| 161 | + | procedure SetMode(Value: TPenMode); override; | |
| 162 | + | procedure SetStyle(Value: TPenStyle); override; | |
| 163 | + | procedure SetWidth(value: Integer); override; | |
| 164 | + | public | |
| 165 | + | constructor Create; override; | |
| 166 | + | destructor Destroy; override; | |
| 167 | + | procedure Assign(Source: TPersistent); override; | |
| 168 | + | property Handle: HPEN read GetHandle write SetHandle; deprecated; | |
| 169 | + | property Reference: TWSPenReference read GetReference; | |
| 170 | + | published | |
| 171 | + | property Color: TColor read FColor write SetColor default clBlack; | |
| 172 | + | property Mode default pmCopy; | |
| 173 | + | property Style default psSolid; | |
| 174 | + | property Width default 1; | |
| 175 | + | end; | |
| 176 | + | ``` | |
| 173 | 177 | ||
| 174 | 178 | Этот класс определен как экземпляр другого **родительского** или класса **предка** (*TFPCustomPen*) от которого он **наследует** все его свойства и методы. Он имеет собственные поля, сгруппированные как | |
| 175 | 179 | ||
| 176 | 180 | - **private(частные)** - это означает, что элементы, определенные здесь, доступны или видимы другим классам или процедурам/функциям, определенным только внутри данного программного модуля (Этот пример - из *Graphics*, так что любой из других классов -*TBitMap*, *TPicture* и т.д. этого же модуля может их использовать). Это как локальные переменные (напр. *FColor*, *FPenHandleCached*) или локально используемые методы (*GetHandle*, *SetHandle*), но можно использовать или ссылаться на элементы, объявленные в секциях **protected** или **public**. | |
| 177 | 181 | - **protected(защищенные)** - это означает, что элементы, определенные здесь, доступны или видимы только классам, произведенным из этого класса - **предка**, и унаследовали его свойства и методы. | |
| 178 | 182 | - **public** - это означает, что элементы, определенные здесь, доступны любому программному модулю, включившему текущий модуль в свою секцию [[Glossary|Uses]] | |
| 179 | 183 | - **published** - подобна секции **public**, но компилятор генерирует типовую информацию, требуемую для автоматического подключения этих классов. Часто список published элементов появляется Инспекторе объектов Lazarus; если список **published** отсутствует, в Инспекторе объектов обычно появляются поля **public**. | |
| 180 | 184 | ||
| 181 | 185 | ### Методы | |
| 182 | 186 | ||
| 183 | 187 | Метод подобен обычной процедуре или функции, но может иметь некие дополнительные **директивы**. | |
| 184 | 188 | ||
| 185 | 189 | Некоторые методы, определенные выше, помечены директивой **virtual (виртуальный)**; другие - **override (аннулируемый)**. | |
| 186 | 190 | ||
| 187 | 191 | - **virtual** означает, что тип, или фактический экземпляр метода не известен во время компиляции, но выбирается во время выполнения в зависимости от того, какая подпрограмма вызывает метод. Он может рассматриваться как заполнитель в определении класса. | |
| 188 | 192 | - **override** означает, что во время выполнения локально данное определение может заменить определение, унаследованное от класса - предка, особенно, если оно было **virtual**. Если необходимо применить метод, определенный в родительском классе, его нужно вызывать специфично, с оговоркой **inherited**. | |
| 189 | 193 | ||
| 190 | 194 | Методы без директив virtual или override являются **статическими** (обычными для Pascal). Методы, имеющие такие директивы, считаются **динамическими**. | |
| 191 | 195 | ||
| 192 | 196 | Методы имеют специальные возможности: | |
| 193 | 197 | ||
| 194 | 198 | - **create** - **constructor** для класса, заботящегося о распределении памяти, сбора всей необходимой информации и настройки/инициализации различных свойств. | |
| 195 | 199 | - **destroy** - **destructor** для класса, упорядоченно удаляющего все составляющие класса из системы, и возвращающего все свои ресурсы системе для повторного использования. | |
| 196 | 200 | ||
| 197 | 201 | ### Свойства | |
| 198 | 202 | ||
| 199 | 203 | Свойства аналогичны простым полям в "Записи" стандартного Pascal, но могут иметь указатели **чтение** и/или **запись**. | |
| 200 | 204 | ||
| 201 | 205 | - Указатель **чтение** является полем или функцией, возвращающим результат корректного типа для свойства. В вышеприведенном примере, свойство *Color* имеет указатель чтения *FColor*, являющийся локальной переменной, которая содержит используемое значение. Если свойство имеет указатель **read** и не имеет **write**, оно служит только для чтения. | |
| 202 | 206 | - Указатель **запись** является полем или процедурой, устанавливающей значение свойства в определенное место. В вышеприведенном примере, *Color* имеет указатель записи *SetColor*, являющийся процедурой (определено в секции **protected**) для записи значения цвета в указанное место. Если свойство имеет указатель **write** и не имеет **read**, оно служит только для записи. | |
| 203 | 207 | - **default** - имеется возможность установки значения свойства по умолчанию **default**. Например, *Color* имеет значение по умолчанию *clBlack*, или черный, во время создания. Впоследствии ему можно присвоить другое значение оператором присвоения в программе или через Инспектор объектов. | |
| 204 | 208 | ||
| 205 | 209 | ## Дальнейшая информация | |
| 206 | 210 | ||
| 207 | 211 | Здесь даны только самые начала темы. Для дальнейшего изучения настоятельно рекомендуется читать руководство [FreePascal](http://lazarus-ccr.sourceforge.net/fpcdoc/ref/ref.html), в особенности главы 5 (**Объекты**) и 6 (**Классы**) | |
| 208 | 212 | ||
| 209 | 213 | --Kirkpatc 11:04, 20 July 2008 (CEST) | |
| 210 | 214 | ||
| 211 | 215 | ------------------------------------------------------------------------ | |
| 212 | 216 | ||
| 213 | 217 | [[Console Mode Pascal/ru]] | |
| 214 | 218 | ||
| 215 | 219 | --- | |
| 216 | 220 | *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).* |
