Лекція 3. Особливості об’єктно-орієнтованого програмування на Delphi
Основою об’єктно-орієнтованого програмування (ООП) є ідея об'єднання в одній структурі даних і дій, які виконуються над цими даними.
Починаючи з 7-ї версії в середовищі Delphi для розробки програм використовується мова програмування Delphi, основу якої складає мова Object Pascal (об’єктно-орієнтоване розширення стандартної мови програмування Pascal). Програмування на мові Delphi означає роботу в інтегрованому середовищі розробки програм (IDE) фірми Borland. При цьому система накладає ряд обмежень, які виходять за рамки специфікації мови Object Pascal. Зокрема, посилюються вимоги до іменування файлів та програм, які не є обов’язковими за рамками IDE.
Одним з найважливіших понять ООП є клас. Клас представляє собою подальший розвиток концепції типу і об’єднує в собі задання не лише структури та розміру змінних, але й операцій, які можуть виконуватись над ними. Об’єкти в програмі завжди є екземплярами того чи іншого класу аналогічно змінним визначеного типу.
До основних концепцій ООП належать наступні.
Інкапсуляція являє собою об’єднання даних та їх методів всередині класу. Це означає, що в класі інкапсулюються (об’єднуються і поміщаються всередину) поля, властивості і методи. При цьому клас отримує певну функціональність.
Наслідування – це процес створення нових об’єктів-нащадків від існуючих об’єктів, при чому нащадок наслідує від батьківського об’єкта усі його поля, властивості та методи. Далі наслідувані поля, властивості і методи можна використовувати в незмінному вигляді або перевизначати (модифікувати).
Просте наслідування значного змісту немає, тому в об’єкт-нащадок додають нові елементи, які визначають його особливості і функціональність. Видалити будь-які елементи батьківського об’єкта в нащадку не можна. Але з нового об’єкта можна створити наступний нащадок. В результаті створюється дерево об’єктів, яке також називається ієрархією класів. В корені цього дерева є базовий клас TObject, який реалізовує найбільш загальні для усіх класів елементи, наприклад, дії по створенню і видаленню об’єкта. Чим далі від кореня дерева знаходиться той чи інший клас, тим більшою специфічністю він володіє.
Наступна концепція ООП – це поліморфізм. Суть поліморфізму полягає у тому, що методи різних класів можуть мати однакові імена, але різний зміст. Це досягається перевизначенням батьківського методу в класі нащадку. В результаті батьківський метод і нащадок ведуть себе по-різному. При цьому звернення до одноіменних методів різних об’єктів виконується аналогічно.
Класи і об’єкти
В мові програмування Object Pascal класи – це спеціальні типи даних, які використовують для опису об’єктів. Відповідно об’єкт, який має тип якого-небудь класу є екземпляром даного класу або змінною цього типу.
Клас являє собою певний тип запису, який вміщає такі елементи, як поля, властивості і методи. Поля класу є аналогічні полям запису і служать для збереження інформації про об’єкт. Методами називаються процедури і функції, призначені для обробки полів. Властивості можна використовувати як поля, наприклад, за допомогою оператора присвоювання, або всередині класу доступ до властивостей виконують методи класу.
Опис класу має наступну структуру:
type <ім’я класу>=class(<ім’я ,батьківського класу>)
private <приватні описи>;
protected <захищені описи>;
public <загальнодоступні описи>;
published <опубліковані описи>;
end;
У приведеній структурі описами є об’явлення властивостей, методів та подій.
Приклад, опису класу:
type TColorCircle=class(TCircle);
FLeft, FTop, FRight, FBottom: Integer;
FColor: TColor;
end;
Тут клас TColorCircle створюється на основі батьківського класу TCircle. В порівнянні з батьківським, новий клас додатково містить чотири поля типу Integer і одне поле типу TColor.
Для різних елементів класу можна встановлювати різні права доступу. Для цього в описі класу використовуються окремі розділи, позначені спеціальними специфікаторами видимості.
Розділи private та protected містять захищені описи, що доступні всередині модуля, в якому вони знаходяться. Описи з розділу protected, крім того, є доступними для породжених класів за межами названого модуля.
Розділ public містить загальнодоступні описи, які видно у будь-якому місці програми, де є доступним даний клас.
Розділ published містить опубліковані описи, які на додаток до загальнодоступних описів породжують динамічну (тобто під час виконання програми) інформацію про тип (Run-Time Type Information, RTTI). За цією інформацією при виконанні програми відбувається перевірка на приналежність елементів об’єкта тому чи іншому класу. Одним з призначень розділу published є забезпечення доступу до властивостей об’єкта при розробці програми. В Інспекторі об’єктів видно ті властивості, які є опублікованими. Специфікатор published встановлюється по замовчуванню.
Об’єкти як екземпляри класу об’являються у програмі в розділі var як звичайні змінні. А для звертання до конкретного елемента об’єкта (до поля, властивості чи методу), як і у випадку запису, вказується ім’я об’єкта та ім’я елемента, розділені крапкою, тобто ім’я елемента є складеним. Наприклад,
var CCircle1: TColorCircle;
begin CCircle1.FLeft:=5;
CCircle1.FTop:=1
end;
Поля класу
Поле класу являє собою дані, які містяться у класі. Поле описується як звичайна змінна і може бути будь-якого типу. Наприклад,
type TNewClass = class (TObject)
private FCode: integer; FSign: char; FNote: string;
end;
Тут новий клас TNewClass створюється на основі базового класу TObject і має додатково три поля. Відповідно до прийнятої домовленості імена полів повинні починатись з префікса F (від англ. Field – поле).
Якщо в якості первинного класу використовується клас TObject, який є базовим для усіх класів, то його ім’я після слова class можна не вказувати.
Як вже зазначалось, при створенні нових класів клас-нащадокок наслідує усі поля первинного класу, при цьому видалити чи перевизначити ці поля неможливо, але можна додати нові. Таким чином, чим далі по ієрархії від батьківського знаходиться клас, тим більше полів він має. Зміна значень полів, як правило, виконується за допомогою методів та властивостей об’єкта.
Властивості об’єкта
Властивості реалізують механізм доступу до полів. Кожній властивості відповідає поле, яке містить значення властивості, і два методи, які забезпечують доступ до даного поля. Опис властивостей починається зі слова property, при цьому тип властивості і відповідного поля повинні співпадати. Ключові слова read і write є зарезервованими всередині об’явлення властивості і служать для вказання методів класу, за допомогою яких виконується зчитування значення поля, пов’язаного з властивістю, або запис нового значення в це поле. Приклад опису властивостей:
type TNewClass=class(TObject)
private
FCode: integer; FSign: char; FNote: string;
published
property Code: integer read FCode write FCode;
property Sign: char read FSign write FSign;
property Note: string read FNote write FNote;
end;
Для доступу до полів FCode, FSign та FNote, які описані в розділі захисту і є недоступними для інших класів, використовуються властивості Code, Sign та Note відповідно.
У контексті програми з властивістю можна працювати як зі звичайним полем.
Методи класу
Метод являє собою підпрограму (процедуру чи функцію), яка є елементом класу. Опис методу подібний до опису звичайної підпрограми модуля. Заголовок методу розміщується в описі класу, а сам код методу знаходиться у розділі реалізації. Ім’я методу у розділі реалізації є складеним і включає в себе тип класу.
Наприклад, опис методу ButClick буде виглядати так:
interface

type TForm1=class(TForm)
But1:TButton;
procedure ButClick(Sender:TObject);
end;

implementation

procedure TForm1.ButClick(Sender:TObject);
begin Close;
end;
За замовчуванням усі методи, які об’являються у класі, є статичними і викликаються як звичайні підпрограми.
Але метод, який об’явлений у класі, може викликатись й іншими способами, що залежать від виду цього методу. Вид методу визначається модифікатором, який вказується в описі класу після заголовку методу і відділяється від заголовка крапкою з комою. Наведемо деякі модифікатори: virtual – віртуальний метод; dynamic – динамічний метод; override – перевизначений метод; message – обробка повідомлення; abstract – абстрактний метод.
У розробника існує засіб самому керувати перевизначенням методів на етапі прогонки програми – т.зв. динамічне заміщення методів. Для цього метод, який перевизначається в батьківському класі, визначається модифікатором virtual або dynamic. У класі-нащадку метод, який буде заміщати батьківський, визначається модифікатором override.
Отримавши директиву virtual, компілятор поміщає інформацію про метод в таблицю віртуальних методів класу (Virtual Method Table – VMT). Неважливо, скільки створено об’єктів класу, - для кожного класу створюється лише одна таблиця віртуальних методів, з якою потім береться адреса відповідного віртуального методу. У таблицю віртуальних методів поміщаються адр