- •Статичні методи.
- •Field identifier expected - очікується ідентифікатор поля.
- •Мал. 2 Схема обмеження виклику перевизначених статичних методів
- •Віртуальні методи і поліморфізм. Конструктор.
- •Procedure Met2; Virtual;
- •Object not initialized - об'єкт не ініціалізував.
- •Error 149: virtual expected - очікується слово virtual.
Лекція №5
Об’єктно-орієнтоване програмування в мові Pascal та Delphi
Лекція №5 |
|
|
Статичні методи. Проблема успадкування. Віртуальні методи і поліморфізм. |
План
|
Статичні методи.
|
|
|
Поліморфізм - це можливість мати декілька методів з одним і тим же ім'ям для різних об'єктів однієї ієрархії, тобто засіб для розвитку об'єктів в нащадках. Воно реалізується тим, що об'єкт-нащадок може перевизначати, тобто замінювати методи предка на нових з тими ж іменами. Який з методів виконуватиметься при зверненні до методу із заданим ім'ям, визначається типом об'єкту (предок або нащадок) і використовуваного методу. Методи об'єктів по способах їх перевизначення можуть бути статичні, віртуальні і динамічні (підклас віртуальних). Відповідно до цього процес установки взаємозв'язку об'єктів і методів може бути:
Статичні методи: По замовчуванню всі методи статичні. Всі раніше розглянуті методи -статичні. Таке найменування методів пов'язане з тим, що визначення і розміщення посилань на них (для виклику методів) проводиться на етапі компіляції і на весь час виконання програми. Це – попереднє скріплення. |
||
|
|
Список формальних параметрів статичних методів може бути різним у методу предка і методів нащадків, перевизначений (замінюючий) цей метод предка.
Із статичним методом пов'язаний спосіб спадкоємства. Якщо в оголошенні нащадка з'являється метод з тим же ім'ям, що і у предка, то в цьому типі і у всіх його нащадках цей метод буде перевизначений. Таким чином, нащадки можуть використовувати перевизначені ними методи предка. Предок може викликати тільки свої методи; методи нащадків для нього недоступні. Таким чином, при використанні статичних методів поліморфізм розповсюджується від поточного рівня ієрархії вниз, до нащадків.
Дії компілятора при обробці методів ієрархії об'єктів для статичних методів:
при виклику методу компілятор встановлює тип об'єкту, що викликає метод;
потім він шукає метод в межах цього типу; знайшовши його, компілятор призначає виклик цього методу;
якщо метод не знайдений, то компілятор розглядає тип безпосереднього предка і шукає метод в його оголошенні:
якщо метод з таким ім'ям знайдений, формується виклик методу цього предка;
якщо метод не знайдений в типі найближчого предка, компілятор переходить до типу предка, наступного в ієрархії предків; і так до тих пір, поки не буде знайдений викликаний метод;
якщо компілятор, дійшовши до верхнього рівня ієрархії, не знайде метод, він видасть повідомлення про помилку номер 44 періоди компіляції:
Field identifier expected - очікується ідентифікатор поля.
Це повідомлення видається, якщо ідентифікатор не відповідає імені поля змінної типу RECORD або типу OBJECT.
|
|
|
Істотне обмеження статичних методів: якщо метод предка викликає інші методи, то це можуть бути тільки методи предка, навіть якщо нащадок має свої власні методи з таким же ім'ям методу. Цей недолік зумовлений тим, що зв'язок об'єкту з методом проводився на етапі компіляції, статично, на весь час виконання програми. Цей недолік статичних методів усувається використанням віртуальних методів. Обмеження статичних методів розглянемо на прикладі лістингу програми. |
||
|
|
Лістинг 1. Виклики статичних методів предка і нащадка.
Program novirt1;
Uses Crt;
Type ObjName1 = object { - оголошення об'єкту-предка }
Fl1 : integer; { - поле }
Procedure Met1; { - методи }
Procedure Met2;
End;
ObjName2 = object (ObjName1) { - оголошення нащадка }
Procedure Met2; { - заміна статичного методу }
End;
{ Методи об'єкту Objname1 }
Procedure ObjName1.Met1;
Begin Met2; { - виклик тільки методу Objname1.Met2!!}
End;
Procedure ObjName1.Met2;
Begin
FL1 := 12;
Writeln ('Працює метод ObjName1.Met2: FL1 = ', FL1)
End;
{ Метод об'єкту ObjName2 }
Procedure ObjName2.Met2;
Begin
FL1 := 34;
Writeln ('Працює метод ObjName2.Met2: FL1 = ', FL1)
End;
Var
V1:ObjName1; { - змінна об'єктного типу - предка }
V2 : ObjName2; { - " " " нащадка }
{---------------- Основна програма ---------------------------------------}
Begin
ClrScr;
Assign (Output, 'Inovirt.res');
Rewrite (Output);
Writeln (‘ОБ'ЄКТИ, СТАТИЧНІ МЕТОДИ’ );
Writeln ('Працюємо з VI - екземпляром типу предка');
V1.Met1; {- викликається метод Met1 для екземпляра V1 - предка }
{ Met1 викликає метод Objname1.Met2 - предка }
V1.Met2; { - безпосередньо викликається метод Objname1.Met2; }
Writeln ('Працюємо з V2 - екземпляром типу нащадка');
V2.Met1; { - викликається метод Met1 для екземпляра V2 - нащадка; Met1 викликає метод Objname1.Met2 - предка, а не Objname2.Met2 - нащадка - в цьому - обмеження }
V2.Met2 { - безпосередньо викликається метод Objname2.Met2; }
Close (Output);
End.