Оголошення класу
Класом у Delphi називається тип даний, оголошений користувачем. Синтаксис оголошення об’єктного класу такий:
Type
<імя класу>=Class {(імя батьківського класу)}
public //доступно всім
<поля, методи, властивості, події>
published //відображаються в Інспекторі Об’єктів і можуть мінятися користувачем
<поля, властивості >
protected //доступ надається тільки потомкам класу
<поля, методи, властивості, події>
private //доступ тільки в модулі
<поля, методи, властивості, події>
End;
Ім’я класу може бути будь-яким допустимом ідентифікатором. Але прийнято ідентифікатори більшості класів починати з символа «Т». Ім’я батьківського класу може не вказуватися. Тоді припускається, що даний клас є безпосереднім спадкоємцем TObject –найзагальнішого з напередвизначених класів. Таким чином, наступні оголошення є еквівалентними:
type TMyClass=class
…
end;
і
type TMyClass=class(TObject)
…
end;
Клас успадковує поля, методи, властивості, події від своїх предків і може відміняти чи перевизначати якісь із цих елементів класу або вводити нові. Доступ до оголошуваних елементів класу визначається тим, в якому класі вони оголошені.
Розділ public(відкритий) призначений для оголошень, які доступні для зовнішнього використання. Це відкритий інтерфейс класу. Розділ published (публікований) містить відкриті властивості, які з’являються в процесі проектування на сторінці властивостей Інспектора Об’єктів і які користувач може встановлювати в процесі проектування. Розділ private(закритий) містить оголошення полів, процедур і функцій, що використовуються лише всередині даного класу. Розділ protected(захищений) містить оголошення, доступні лише для потомків оголошуваного класу. Як і у випадку закритих елементів, можна приховати деталі реалізації захищених елементів від кінцевого користувача. Однак, на відміну від закритих, захищені елементи залишаються доступними для програмістів, які захочуть створювати від цього класу похідні об’єкти, причому не вимагається, щоб похідні об’єкти оголошувалися в тому ж модулі.
Оголошення полів виглядають так само, як оголошення змінних чи оголошення полів у записах:
<імя поля>:<тип>;
Оголошення методів у найпростішому випадку теж нічим не відрізняються від звичайних оголошень процедур та функцій.
Властивості
Виходячи з принципу інкапсуляції, поля даних завжди мають бути захищеними від несанкціонованого доступу. Доступ до них, як правило, повинен здійснюватися через властивості, що включають методи читання і запису полів. Тому поля доцільно оголошувати в розділі private – закритому розділі класу. Зрідка їх можна поміщати в protected -захищеному розділі класу, щоб можливі потомки даного класу мали до них доступ. Традиційно ідентифікатори полів співпадають з іменами відповідних властивостей, але з додаванням у якості префікса символа 'F'.
property <ім’я>:<тип> read <ім’я поля чи методу читання> write <ім’я поля чи методу запису> <директиви запам’ятовування>
Якщо в розділах read чи write записане ім’я поля, то передбачається пряме читання чи запис даних.
Якщо в розділі read записане ім’я методу читання, то читання буде здійснюватися лише функцією з цим іменем. Функція читання – це функція без параметру, що повертає значення того типу, який оголошений для властивості. Ім’я функції читання прийнято починати з префіксу Get, після якого йде ім’я властивості.
Якщо в розділі write записане ім’я методу запису, то запис буде здійснюватися лише процедурою з цим іменем. Процедура запису – це процедура з одним параметром того типу, який оголошений для властивості. Ім’я процедури запису прийнято починати з префіксу Set, після якого йде ім’я властивості.
Якщо розділ writeвідсутній в оголошенні властивості, значить це властивість лише для читання і користувач не може задавати його значення.
Директиви запам’ятовування визначають, як потрібно зберігати значення властивості при збереженні користувачем форми .dfm. Найчастіше використовується директива
default <значення по замовчуванню>
Вона не задає початкових умов, це завдання конструктора. Директива просто оголошує, що якщо користувач в процесі проектування не поміняв значення властивості за замовчуванням, то зберігати значення властивості не потрібно.
Приведемо приклад. Нехай потрібно оголосити клас з іменем MyClass, що є безпосереднім спадкоємцем TObject і має властивість цілого типу з іменем А. Тоді оголошення цього класу може мати вигляд:
type
MyClass=class(TObject)
private
FA: integer;
protected
procedure SetA(Value:integer); //процедура запису
published
property A: integer read FA write SetA default true;
end;
Тут вводиться закрите поле FA, оголошується захищена функція SetA, що використовується для запису значення цього поля, і вводиться опублікована властивість А, яка оперує цим полем. В оголошенні властивості після ключового слова read записане просто ім’я поля. Це означає, що функція читання відсутня і користувач може безпосередньо читати знаення поля. Після ключового слова writeйде посилання на функцію запису SetA, за допомогою якої в поле А будуть записуватися нові значення. В цій функції можна передбачити якісь перевірки допустимості введеного значення А.
Опис цієї функції повинен поміщатися в розділ implementation модуля, в якому оголошений клас, і може мати вигляд
procedure MyClass.SetA(Value:integer);
begin
if…
then FA:=Value;
end;
В приведеному прикладі опис властивості А поміщений в розділ published. Отже, якщо цей клас описує створений нами новий компонент, то після його встановлення в системі властивість А з’явиться у вінкі Інспекторі Об’єктів при використанні цього компонента. Якщо перенести оголошення властивості в розділ public, то властивістю можна буде користуватися лише під час виконання програми, бо у вікні Інспектора Об’єктів воно не з’явиться. Якщо видалити з означення властивості слово writeз наступним посиланням на функцію запису, то властивість стане властивістю тільки для читання, оскільки поміняти її безпосередньо буде неможливо
Методи та їх успадковування, поліморфізм
При описі нового класу можна додавати нові методи і властивості, залишаючи методи і властивості батьківського класу, а можна батьківські методи і властивості перевизначити.
У Delphi існує чотири види методів: статичні, віртуальні, динамічні та абстрактні.
За замовчуванням всі методи є статичними. Якщо у класі-спадкоємці перевизначити такий метод (тобто ввести новий метод з таким самим іменем), то для об’єктів цього класу новий метод відмінить батьківський. Якщо звернутитися до об’єкту цього класу, то буде викликатися новий метод. Але коли звернутися до об’єкта як до об’єкта батьківського класу, то викличеться батьківський метод.
Віртуальні та динамічні методи не зв’язані з іншими методами з тим же іменем у класах-спадкоємцях. Якщо у класах-спадкоємцях ці методи перезавантажені, то при звертанні до такого методу під час виконання буде викликатися той з методів з однаковими іменами, який відповідає класу об’єкта, вказаному при виклику. Наприклад, якщо є базовий клас графічних об’єктів TShape(геометрична фігура) і ряд його класів-спадкоємців різних геометричних фігур і в кожному з цих класів визначений свій віртуальний метод Draw, що малює цю геометричну фігуру, то можна написати в програмі:
var ShapeArray: array[1..10] of TShape;
…
for i:=1 to 10 do ShapeArray[i].Draw;
В цьому коді в масив ShapeArrayможуть поміщатися об’єкти різних класів, які є спадкоємцями TShape.В циклі звертання до об’єктів відбувається як до об’єктів базового для них типу TShape. В цьому випадку для кожного об’єкта буде викликатися віртуальний метод Draw саме цього об’єкта. Такий підхід, що полегшує роботу з багатьма спорідненими класами, називається поліморфізмом.
При оголошенні в класі віртуальних і динамічних методів використовуються ключові слова virtual і dynamic.
Щоб перезавантажити у класі-спадкоємцю віртуальний метод, потрібно після його оголошення поставити ключове слово override.
Якщо у якомусь базовому класі метод був оголошений як віртуальний, то він залишається віртуальним у класах-спадкоємцях будь-якого рівня. Тобто, на відміну від знайомого нам Pascal-ю, повторно оголошення virtual писати не потрібно. Однак звичайно для полегшення розуміння кодів перезавантажені методи прийнято повторно оголошувати віртуальними, щоб їх суть була зрозуміла для розробників спадкоємців даного класу. Наприклад:
procedue Draw;override;virtual;
Динамічні методи описуються за допомогою ключового слова dynamic і їх призначення таке саме, як і в Pascal-і, тобто вони відрізняються від віртуальних лише за внутрішнім механізмом їх викликів. В цілому віртуальні методи забезпечують зручніші механізми поліморфізму, а динамічні зручніші, якщо у базовому класі визначено багато перезавантажуваних методів і вони одночасно використовуються багатьма об’єктами класів-спадкоємців.
Абстрактний метод – це віртуальний або динамічний метод, реалізація якого не визначена в класі, де він оголошений. Припускається, що цей метод буде перезавантажений у класах-спадкоємцях. Тільки в тих класах, в яких він перезавантажений, його можна викликати.
Оголошується абстрактний метод за допомогою ключового слова abstractпісля слова virtualчи dynamic.Наприклад
procedure DoSomething; virtual; abstract;
Будь-який метод – і статичний і віртуальний – може бути перезавантажений за допомогою ключового слова override.Для віртуальних методів у цьому випадку треба ще додати слово reintroduce.Якщо перезавантажені таким способом методи відрізняються числом чи типом параметрів (так званою сигнатурою), то при виклику методу з класу-спадкоємця буде викликатися той метод, список параметрів якого відповідає списку аргументів.
При реалізації методу, перевизначеного будь-яким способом у класі-спадкоємці, можна викликати метод батьківського класу. Для цього перед іменем методу при його виклику записується ключове слово inherited.
Якщо записати слово inheritedі після нього не писати імені викликаного методу, то буде викликатися успадкований метод з таким самим іменем, як і метод, що з нього він викликається.
Конструктори і деструктори
Конструктори – це спеціальні методи, які створюють та ініціалізують об’єкт. Об’єкт створюється виділенням для нього області в динамічно розподіленій пам’яті. Оголошення конструктора виглядає так само, як і оголошення процедури, але починаються ключовим словом constructor. В якості імені конструктора звичайно задають ім’я Create.Часто в конструктор передають в якості параметра власника об’єкту. Власник об’єкту Owner – це той об’єкт, при знищенні якого знищується і даний об’єкт. Приклади оголошення конструкторів:
constructor Create;
constructor Create(Owner:TComponent);
При реалізації конструктора звичайно першим йде виклик успадкованого конструктора за допомогою ключового слова inherited.В результаті ініціалізуються всі успадковані поля. При цьому порядковим типам в якості початкового значення задається 0, вказівникам – nil,рядки задаються порожніми, а поля типуVariant – Unassigned.Потім ініціалізуються нові поля, введені в даному класі.
Деструктори – це спеціальні методи, які знищують об’єкт і вивільняють зайняту ним пам’ять. Оголошення деструктора виглядає так само, як оголошення процедури, але починається ключовим словом destructor.В якості імені деструктора звичайно задають ім’я Destroy.Реалізація деструктора як правило завершується викликом успадкованого деструктора за допомогою ключового слова inherited,щоб вивільнити пам’ять, виділену для успадкованих полів.
Події
Подія – це спеціальна властивість, що є вказівником функції. Тип узагальненого вказівника на функцію, якій передається один параметр типу TObject – TNotifyEvent. Приклади подій – OnClick, FormCreate, FormClose, OnMouseMove.
Приклад реально оголошеного класу (Програма 10.1)
type
TEditBukwa = class(TEdit)
private
{ Private declarations }
FClear:TNotifyEvent;
FEnableBukwa:boolean;
FEnableLet:boolean;
FModified:boolean;
protected
{ Protected declarations }
procedure SetEnableBukwa(Value:boolean);
procedure SetEnableLet(Value:boolean);
procedure KeyPress(var Key:Char);override;
public
{ Public declarations }
property Modified:boolean read FModified default true;
constructor create(AOwner:TComponent);override; //конструктор
procedure Clear;override;
published
{ Published declarations }
property OnClear:TNotifyEvent read FClear write FClear;
property EnableBukwa:boolean read FEnableBukwa write SetEnableBukwa default true ;
property EnableLet:boolean read FEnableLet write SetEnableLet default true;
end;
Програма 10.1
Підсумок
Delphi успадковує всі можливості роботи з об’єктами, які існують у Pascal-і, але, водночас, має багато нових можливостей. Об’єкт у Delphi – це сукупність властивостей, методів і подій, на які він може реагувати. Об’єктний тип називається класом. Рівень доступності/захищеності елементів класу визначається одним з чотирьох ключових слів: public, published, protected, private. При описі нового класу можна додавати нові методи і властивості, залишаючи методи і властивості батьківського класу, а можна батьківські методи і властивості перевизначити. У Delphi існує чотири види методів: статичні, віртуальні, динамічні та абстрактні. Спеціальні типи методів для створення і видалення об’єктів – конструктори і деструктори. Важливою характеристикою об’єкту є події, на які він реагує (клацання мишкою, натиск клавіші Ввід і т.д.)
Питання по темі
1. Яке ключове слово входить до опису об’єктного типу в Delphi?
а) class
б) object
в) ClassOfObject
2. Як називається найзагальніший з напередвизначених класів (TObject)
3. Рівень доступності/захищеності елементів класу визначається одним з ключових слів:
а) public, published, protected, private
б) public, private
в) private
4. Стандартні імена для конструкторів та деструкторів у Delphi
а) Init; Done
б) Create; Destroy
в) Constructor; Destructor
5. Різновиди методів у Delphi
а) статичні, віртуальні, динамічні та абстрактні.
б) статичні, віртуальні, динамічні
в) статичні, віртуальні, дружні
Лекції 11-13
Створення простого класу
Визначення класу
Приховування даних
Дані класу
Методи класу
Приховування даних і доступність функцій
Методи класу всередині визначення класу
Використання класу
Повідомлення
Об’єкти програми і об’єкти реального світу
Клас як тип даних
Конструктори
Деструктори
Визначення методів класу поза класом та операція глобального дозволу
Об’єкти в якості аргументів
Конструктор копіювання за замовчуванням
Об’єкти, що повертаються функцією
Класи, об’єкти та пам’ять
Статичні дані класу
Роздільне оголошення і визначення полів класу
Константні методи
Константні об’єкти
Підсумок
Питання по темі
Тема 4 -Об’єкти і класи в С++
Мова С++ є класикою об’єктного програмування: вона створювалася саме з метою якомога повніше втілити ООП-підхід. Але, оскільки ми вже ознайомлені з принципами ООП і деякими способами його втілення, то відразу ж розпочнемо зі створення простого об’єктного класу, а потім будемо робити необхідні пояснення. Зауважимо тільки, що об’єктний тип в С++, як і в Delphi, називається класом, конкретні представники цього класу - об’єктами.
Дата добавления: 2015-08-26; просмотров: 2383;