
- •Передмова
- •Розділ 1 об'єктний підхід у програмуванні
- •1.1.Причини виникнення ооп
- •1.1.1.Складність об'єкта дослідження
- •1.1.2.Складність процесу розробки програмного забезпечення
- •1.1.3.Складність опису окремих елементів
- •1.2.Парадигма ооп
- •1.3.Історія розвитку ооп
- •Розділ 2 об'єкти й класи: інкапсуляція
- •2.1.Структура об'єкта й класу
- •2.2.Особливості опису класів у мовах ооп
- •2.2.1.Опис класів в SmallTalk
- •2.2.3.Опис класів в Delphi
- •2.2.4.Опис класів в Java
- •2.3.Поля даних та їх ініціалізація
- •2.3.1.Визначення полів даних в SmallTalk
- •2.3.3.Визначення полів даних в Delphi
- •2.3.4.Визначення змінних в Java
- •2.4.Доступ до даних
- •2.4.1.Доступ до даних в SmallTalk
- •2.4.3.Доступ до даних в Delphi
- •2.4.4.Доступ до даних в Java
- •2.5.Спеціальні змінні
- •2.5.1.Спеціальні змінні в SmallTalk
- •2.5.3.Спеціальні змінні в Java
- •2.5.4.Спеціальні змінні в Delphi
- •2.6.Посилання
- •2.6.1.Визначення посилань в SmallTalk, Delphi і Java
- •2.7.Методи
- •2.7.1.Загальна схема визначення методу
- •2.7.2.Визначення методів в SmallTalk
- •2.7.4.Визначення методів в Delphi
- •2.7.5.Визначення методів в Java
- •2.8."Дружні" методи
- •2.8.2.Аналог дружніх функцій в Delphi
- •2.9.Конструктори й деструктори
- •2.9.1.Конструктори й деструктори в SmallTalk
- •2.9.3.Конструктори й деструктори в Delphi
- •2.9.4.Конструктори й деструктори в Java
- •2.10.Властивості
- •2.10.1.Властивості в Delphi
- •2.10.2.Властивості в Java
- •2.12.Абстрактні методи
- •Розділ 3 успадкування
- •3.1.Форми успадкування
- •3.2.Успадкування в SmallTalk
- •3.3.1.Віртуальне успадкування
- •3.3.2.Правило сумісності типів
- •3.3.3.Використання конструкторів і деструкторів при успадкуванні
- •3.4.Успадкування в Delphi
- •3.4.1.Ієрархія класів в Delphi
- •3.4.2.Створення нових компонентів
- •3.5.Успадкування в Java
- •3.5.1.Використання ключового слова super
- •3.5.2.Клас Object
- •Розділ 4 поліморфізм
- •4.1.Віртуальні методи
- •4.2.1.Механізм пізнього зв'язування
- •4.2.2.Таблиця віртуальних методів
- •4.3.Поліморфізм в Delphi
- •4.3.1.Заміщення віртуальних і динамічних методів
- •4.3.2.Приведення типів
- •4.4.Поліморфізм в Java
- •4.5.Поліморфізм в SmallTalk
- •5.1.Потокові класи
- •5.1.1.Ієрархія потокових класів
- •5.1.2.Форматоване введення/ виведення
- •5.1.3.Маніпулятори
- •5.1.4.Введення/виведення у файл
- •5.2.Контейнерні класи
- •5.2.1.Ітератори
- •5.2.2.Визначення контейнерних класів
- •5.2.3.Стандартні контейнерні класи
- •5.3.1.Параметиізовані класи (шаблони)
- •5.3.2.Ітератори stl
- •5.3.3.Узагальнені алгоритми
- •Література
- •Додатки лабораторна робота №1 об'єкти й повідомлення в smalltalk
- •Лабораторна робота №2 класи й методи в smalltalk
- •Листинг 3.1
- •Листинг 3.2
- •Листинг 3.3
- •Лабораторна робота 5 компоненти в delphi
- •Лабораторна робота 6 меню й вікна в delphi
- •Лабораторна робота 7 розробка меню в java
- •Лабораторна робота 8 робота з подіями в java
4.2.1.Механізм пізнього зв'язування
Як ми вже відзначали вище, зв'язок установлювана між об'єктами й методами на етапі виконання програми називається пізнім зв'язуванням Розглянемо його суть.
Побудуємо ієрархію класів “Точка-Коло”:
class Point {
public:
int x,y;
virtual void SwOn();
virtual void SwOff();
void SwMove(int, int);
};
class Circle : public Point {
public:
int r;
void SwOn();
void SwOff();
};
Point::SwMove (int i, int j){
SwOff();
x = x + i;
y = y + j;
SwOn();
}
void main () {
Point * pPoint;
Circle * pCircle;
pPoint(Move(10,20);
pCircle(Move(20,30);
}
Я
кби
методи SwOn і SwOff не були оголошені як
віртуальніто ми б
мали схему виклику методу Move, показану
на рис. 4.1.
Рис. 4.1. Схема раннього (статичного) зв'язування
В обох випадках були б викликані методи класу Point.
П
ри
віртуальному оголошенні методів SwOn
і SwOff установлюється динамічний
зв'язок з методами, як це показано на
рис. 4.2.
Рис. 4.2. Схема пізнього (динамічного) зв'язування
У результаті для об'єкта типу Point будуть викликані його методи SwOn і SwOff, а для об'єкта типу Circle – свої.
Для забезпечення динамічного виклику функцій SwOff і SwOn необхідно:
розірвати статичний зв'язок між Point::Move і Point::SwOn (Point::SwOff);
забезпечити можливість для методу Move викликати методи SwOn і SwOff залежно від того, для якого об'єкта викликаний метод Move.
Це досягається за рахунок створення спеціальної таблиці віртуальних методів (Virtual Method Table – VMT).
4.2.2.Таблиця віртуальних методів
С
хема
побудови й використання VMT для класів
Point і Circle наведена на рис. 4.3.
Рис. 4.3. Схема побудови й використання VMT.
Тут K – контрольна сума
VMT створюється автоматично в статичній пам'яті на етапі компіляції для класів, які містять хоча б один віртуальний метод. Кожний об'єкт такого класу має покажчик на VMT свого класу. Ініціалізуєтся цей показник при виклику конструктора, тобто конструктор не тільки виділяє динамічну пам'ять під об'єкт та ініціалізує поля даних об'єкта, але й встановлює зв'язок між об'єктом і відповідної VMT. Поле VMT «Розмір об'єкта» задає величину необхідної для розміщення об'єкта пам'яті, а поле «K» служить для перевірки факту встановлення зв'язку з VMT.
Адреси віртуальних методів в VMT задаються як зсув від початку таблиці. При виклику віртуального методу встановлюється зв'язок між змінною this, класом об'єкта і його VMT. Якщо зв'язок установлений успішно (перевіряється по полю «K»), то керування передається на код необхідного віртуального методу шляхом вказівки відповідного зсуву. Таким чином, структура створювана при пізньому зв'язуванні забезпечує побудову двійкового формату для зв'язаних об'єктів.
О
бласть
даних VMT суперкласу повинна входити
в усі VMT класів-нащадків, причому у
всіх їх VMT методи базового класу
повинні мати однаковий зсув, як це
показано на рис. 4.4.
Рис. 4.4. Зв'язок VMT при побудові ієрархії класів
Для використання механізму пізнього зв'язування необхідно, щоб класи з віртуальними методами мали конструктори, які не можна визначати віртуальними. Що стосується деструкторів, то для коректного звільнення пам'яті, займаної об'єктом, їх переважно визначати, як віртуальні методи. Якщо віртуальна функція є одночасно й inline, то підстановка тіла функції здійснюється тільки в тому випадку, коли механізм віртуального виклику ігнорується. Наприклад, так відбувається при виклику функції з використанням кваліфікатора <::>.
Застосування пізнього зв'язування має свої достоїнства й недоліки. До числа останніх відносяться: збільшення витрати пам'яті на створення VMT, а так само збільшення часу для виклику методів через VMT. Однак зазначені недоліки компенсуються гнучкістю, що дає поліморфізм.