
- •Передмова
- •Розділ 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
5.3.1.Параметиізовані класи (шаблони)
Для мов зі строгим контролем типів даних успадкування є не кращий спосіб побудови контейнерних класів, тому що в цьому випадку необхідно вводити нові підкласи й у підсумку бібліотека сильно розростається. Інший шлях полягає в розробці класів, у яких тип передається як параметр. Такі класи називаються параметризованими шаблонами.
template <class T> class List {
// T - параметр шаблон, тип даних, альтернатива (void*)
public:
void addElement(T newValue);
T firstElement();
ListIterator <T> iterator();
private:
Link <T>* firstLink;
};
Template <class T> class Link {
public:
T value;
Link * nextLink;
Link (T, Link*);
};
Функції, які визначають методи в шаблоні класу, повинні так само описуватися як шаблони.
template <class T> void List <T>::addElement (T newValue) {
firstLink = new Link(newValue, firstLink);
//першим елементом стає той, котрий тільки що доданий
}
template <class T> T List <T>:: firstElement(){
Link* first = firstLink;
T result = first ( value;
FirstLink = first ( nextLink;
delete first;
return result;
}
template <class T> Link<T>::Link (T v, Link *n):value(v), nextLink(n) {};
Використовуючи таке визначення, зручно створювати списки різного типу:
List <int> one; //список цілих
List <double> two; //список дійсних
List <char> three; //список символів
Крім явних достоїнств, які складаються в зручності використання шаблонів, вони мають і ряд недоліків:
Шаблон не дозволяє визначати списки різнотипних даних, тому що всі елементи повинні відповідати оголошеному типу. Однак цей недолік можна обійти, якщо замість елементів зберігати покажчики на них.
Використання шаблонів приводить до різкого збільшення коду, тому що їхня реалізація в основному інтерпретується через складні макроси. У результаті для кожного нового параметра створюються нові класи й реалізації методів.
5.3.2.Ітератори stl
Ітератори STL складаються з пар значень, що відзначають початок і кінець контейнерних структур, тобто задають деякий діапазон значень. Причому кінцеве значення ітератора розглядається не як частина обумовленого діапазону, а як позамежний елемент. Коли інкрементація (++) застосовується до ітератора, що вказує на останній елемент у послідовності, то ітератор приймає позамежне значення. Оператор разйменування (*) здійснює доступ до даних, що визначаються ітератором. Крім того, у стандартних контейнерних класах ітератор, що вказує на початок діапазону, визначається функцією begin(), а на кінець діапазону – функцією end().
Контейнерний клас, що входить в STL, не використає ітератор, як “дружні” класи, визначає тип даних для ітератора, а також методи, які повертають значення ітератора. Наприклад, інтератор для класу списку визначається в такий спосіб:
template <class T> class List {
public:
typedef ListIterator <T> iterator;
iterator begin(){
// повертає ітератор у вихідний стан
return ListIterator <T> (firstLink);
}
iterator end(){
// повертає позамежний елемент
return ListIterator <T> (0);
}
};
template <class T> class ListIterator {
public:
ListIterator (Link <T>* sl):currentLink(sl) {};
void operator ++ (){
// перехід до наступного елемента
currentLink = current ( nextLink;
}
T operator * (){
//повернути поточний елемент (разйменування)
return currentLink ( value;
}
bool operator = = (ListIterator <T>& rigth){
return current = = rigth.currentLink; };
private:
Link <T>* currentLink;
};
Тепер ітератор може бути оголошений й ініціалізований деяким списком:
List <int> aList;
List <int>:: iterator start = aList.begin();
List <int>:: iterator end = aList.end();
А сам цикл поелементного перегляду буде виглядати так:
for(;iterator itr != end; itr++)
{cout << (*itr) << endl;}