images.jpg

 

 

Попередня сторінка          Зміст           Наступна сторінка          Електронні посібники ВНТУ

 

 

 

 

 

ЛАБОРАТОРНА РОБОТА № 12

КЛАСИ ЯК ОСНОВА ООП.  ОБ'ЄКТИ ТИПУ КЛАС

images (52).jpg
 

Мета роботи

  • Порівняти об'єктно-орієнтований та функціональний підходи у програмуванні.
  • Ознайомитись на практиці  з класами, об'єктами та головними елементами об'єктного підходу.
  • Навчитись створювати і використовувати об’єкти типу клас.
  • Навчитись на практиці застосовувати успадкування класів, створювати ієрархію класів.

 

 
 images (47).jpg
        

       ТЕОРЕТИЧНІ ВІДОМОСТІ

 

 

Класи та об'єкти в С++

Класи та об'єкти в С ++ є основними концепціями об'єктно-орієнтованого програмування (ООП). Об'єктно-орієнтоване програмування – розширення структурного програмування, в якому основними концепціями є поняття класів і об'єктів. Основна відмінність мови програмування С++ від С полягає в тому, що в С немає класів, а отже мова С не підтримує ООП, на відміну від С++.

Класи в С++ – це абстракція, що описує методи і властивості ще не існуючих об'єктів. Об'єкти – конкретне уявлення абстракції, що має свої властивості та методи. Створені об'єкти на основі одного класу називаються екземплярами цього класу. Ці об'єкти можуть мати різну поведінку, властивості, але все одно будуть об'єктами одного класу. В ООП існує три основних принципи побудови класів:

1. Інкапсуляція – це властивість, що дозволяє об'єднати в класі і дані, і методи, які працюють з ними і приховати деталі реалізації від користувача.

2. Успадкування – це властивість, що дозволяє створити новий клас-нащадок на основі вже існуючого, при цьому всі характеристики класу батька присвоюються класу-нащадку.

3. Поліморфізм – властивість класів, що дозволяє використовувати об'єкти класів з однаковим інтерфейсом без інформації про тип і внутрішній структурі об'єкта.

Оголошення класів в С++

class // ім'я класу

{

   private:

     // Список властивостей і методів для використання всередині класу

   public:

     // Список методів доступних іншим функціям та об'єктам програми

   protected:

     // список засобів, доступних при спадкуванні

};

Приклад.  Програма, в якій оголошено найпростіший клас, в якому оголошена одна функція, яка друкує повідомлення.

#include <iostream>

using namespace std;

     // оголошення класу

class CppClass

{

  public: // специфікатор доступу

     void message () // функція виводить повідомлення на екран

     {

         cout << "  Classes and Objects in C++ \n\n\n";

     }

};   // Кінець оголошення класу CppStudio

 

int main (int argc, char * argv [])

{

     CppClass obj;         // Оголошення об'єкта

     obj.message();       // Виклик функції класу message

     system("pause");

     return 0;

}

 

set-функції та get-функції класів

Кожен об'єкт має якісь свої властивості або атрибути, які характеризують його впродовж усього життя. Атрибути об'єкта зберігаються в змінних, оголо­шених всередині класу, якому належить даний об'єкт. Причому, оголошення змінних повинно виконуватися зі специфікатором доступу private. Такі змінні називаються елементами даних або полями класу. Оскільки елементи даних оголошені в private, то і доступ до них можуть отримати тільки методи класу, зовнішній доступ до елементів даних заборонений. Тому прийнято оголо­шувати в класах спеціальні методи – так звані set і get функції, за допомогою яких можна маніпулювати елементами даних. set-функції ініціалізують елементи даних, get-функції дозволяють переглянути значення елементів даних.

Доопрацюємо клас CppClass так, щоб у ньому можна було зберігати дату в форматі дд.мм.гг. Для зміни і перегляду дати реалізуємо set- і get-функції.

class CppClass // ім'я класу

{

   private:

     int day,   // день

         month, // місяць

         year;  // рік

   public:

     void message () // функція виводить повідомлення на екран

     {   cout << "\n\tClasses and Objects in C++ \n\n";

     }

     void setDate (int date_day, int date_month, int date_year)

     {   day = date_day;        // Ініціалізація дня

         month = date_month;    // Ініціалізація місяця

         year = date_year;      // Ініціалізація року

     }

     void getDate () // відобразити поточну дату

     {

       cout<<"\n\tDate:"<<day<<"."<<month<<"."<<year<<endl<<endl;

     }

};         // Кінець оголошення класу CppStudio

 

int main ()

{    setlocale (LC_ALL, "rus"); // Установка локалі

     int day, month, year;

     cout << "\n\tВведiть поточний день, мiсяць i рiк: \n\n";

     cout << "\tдень  : "; cin >> day;

     cout << "\tмiсяць: "; cin >> month;

     cout << "\tрiк   : "; cin >> year;

     CppClass obj;         // Оголошення об'єкта

     obj.message ();      // Виклик функції класу message

     obj.setDate (day, month, year); // Ініціалізація дати

     obj.getDate ();      // Відобразити дату

     system ("pause");

     return 0;

}

        Результат:

 

 

 

 

 

У визначенні класу специфікатор доступу private обмежує доступ до змін­них, які оголошені після нього і до початку специфікатора доступу public. Таким чином, до змінних daymonthyear, можуть отримати доступ тільки методи класу. Функції, що не належать класу, не можуть звертатися до цих змінних. Дані або методи класу, оголошені після специ­фі­катора доступу private, але до початку наступного специфікатора досту­пу називаються закритими елементами даних і закритими методами класу.

Доцільно оголошувати елементи даних після специфікатора доступу private, а методи класу – після специфікатора public. Тоді, для мані­пулювання елементами даних, оголошуються спеціальні функції – get і set.

В клас CppClass ми додали два методи setDate() і getDate(). Метод setDate() (set-функція) инициализирует елементи даних. Тобто метод setDate() ініціалізує змінні daymonthyear.

Щоб переглянути, значення закритих елементів даних, оголошена функція getDate() (get-функція), яка повертає значення з змінних daymonthyear у вигляді дати.

 

Конструктори і деструктори

Коли ми створюємо елементи (змінні) класу, ми не можемо присвоїти їм значення у самому визначенні класу. Компілятор видасть помилку. Тому нам необхідно створювати окремий метод (так звану set-функцію) класу, за допомогою якого і буде відбуватися ініціалізація елементів. При цьому, якщо необхідно створити, наприклад, 20 об'єктів класу, то прийдеться 20 разів викликати set-функції. Тут нам якраз зможе допомогти конструктор класу.

Конструктор (construct – створювати) – це спеціальний метод класу, при­зна­чений для ініціалізації елементів класу деякими початковими значеннями.

Деструктор (destruct – руйнувати) – спеціальний метод класу, який служить для знищення елементів класу. Найчастіше його використовують тоді, коли в конструкторі, при створенні об'єкта класу, динамічно була виділена ділянка пам'яті і необхідно цю пам'ять очистити, якщо ці значення вже не потрібні для подальшої роботи програми.

Важливо пам'ятати:

  1. конструктор і деструктор завжди оголошуємо в розділі public;
  2. при оголошенні конструктора тип повернення не вказується, в тому числі – void !!!;
  3. у деструктора так само немає типу повернення, деструктору не можна передавати ніяких параметрів;
  4. ім'я класу і конструктора повинні бути ідентичними;
  5. ім'я деструктора ідентично імені конструктора, але з приставкою ~;
  6. у класі допустимо створювати декілька конструкторів, якщо це необхідно. Імена будуть однаковими, а компілятор буде їх розрізняти по переданим параметрами (перевантаження функцій). Якщо ми не передаємо в конструктор параметри, він вважається конструктором за замовчуванням;
  7. у класі може бути оголошений лише один деструктор.

 

Приклад.

 

class AB //класс

{

    private:

          int a;

          int b;

    public:

    AB()    //це конструктор 

    {   a = 0; b = 0;      //початкові значення полів

        cout << "\n\n\tРобота конструктора: " << endl;

        cout << "\ta = " << a << endl;

        cout << "\tb = " << b << endl << endl;

    }

    void setAB() // змінюємо початкові значення

    {   cout << "\tВведите целое число а: ";  cin >> a;

        cout << "\tВведите целое число b: ";  cin >> b;

    }

    void getAB()

    {   cout << "\ta = " << a << endl;

        cout << "\tb = " << b << endl << endl;

    }

};

 

int main()

{   setlocale(LC_ALL, "rus");

    AB obj1;         //спрацює конструктор для І об’єкта

    obj1.setAB();   //задаємо нові значення

    obj1.getAB();   //виводимо їх на екран

    AB obj2;         //спрацює конструктор для ІІ об’єкта

     system("pause");

     return 0;

}

                Результат:

 

 

 

 

 

 

 

 

 

Успадкування класів

Упадкування класів дозволяє створювати похідні класи (класи спадкоємці), взявши за основу всі методи й елементи базового класу (класу батька). Таким чином, економиться маса часу на написання і налагодження коду нової про­гра­ми. Об'єкти похідного класу вільно можуть використовувати все, що створено і налагоджено в базовому класі. При цьому ми можемо в похідний клас дописати необхідний код для удосконалення програми: додати нові поля, методи і т. д. Базовий клас залишиться недоторканим. Нижче наведено код програ­ми, в якій створено два класи: базовий – FirstClass і похідний від нього SecondClass.

Приклад

class FirstClass    // базовий клас

{

protected:          // специфікатор доступу до элементу value

    int value;

public:

    FirstClass()       {  value = 0;   }

    FirstClass(int x)  {  value = x;   }

    void show_value()  {  cout << value << endl;  }

};

 

class SecondClass : public FirstClass   // похідний клас

{

public:

          // конструктор класу SecondClass викликає конструктори класу

          // FirstClass

    SecondClass() : FirstClass() {} 

    SecondClass(int inputS) : FirstClass(inputS) {} 

    void ValueSqr() // Без специфікатора  protected не змогли б змінити value

    {

        value *= value;   

    } 

};

 

int main()

{   setlocale(LC_ALL, "rus");

   

    FirstClass F_object(3);     // об’єкт базового класу

    cout << "\n\tvalue F_object = ";

    F_object.show_value();

 

    SecondClass S_object(4);    // об’єкт похідного класу

    cout << "\tvalue S_object = ";

    S_object.show_value();      // виклик методу базового класу

 

    S_object.ValueSqr();        // підносимо value до квадрату

    cout << "\tквадрат value S_object = ";

    S_object.show_value();

 

    // F_object.ValueSqr();      // ПОМИЛКА: немає доступу

    cout << endl;

    system("pause");

    return 0;

}

                         Результат:

 

Основна інформація про успадкування класів:

     

  1. Успадкування – це визначення похідного класу, який може звертатися до всіх елементів і методів базового класу, за винятком тих, що перебувають у розділі private.
  2. Похідний клас ще називають нащадком або підкласом, а базовий – батьківським, або надкласом, або суперкласом.

  3. Синтаксис визначення похідного класу:
  4. class Імя_Похідн_Класу: специфікатор доступу Імя_Баз_Класу {  . . .   };

  5. Похідний клас має доступ до всіх полів і методів базового класу, а базовий клас може використовувати тільки свої власні поля і методи.
  6. У похідному класі необхідно явно визначати свої конструктори, деструк­тори і перевантажені оператори присвоювання через те, що вони не успадковуються від базового класу. Але їх можна викликати явним чином при визначенні конструктора, деструктора або перевантаження оператора присвоєння похідного класу, наприклад, таким чином (для конструктора):

Конструктор_Похідн_Класу (...): Конструктор_Баз_Класу (...) {...}.

 

images (37).jpg

 

Порядок виконання роботи

 

 

  1. Засвоїти теоретичний матеріал. Використовуючи лекційний матеріал і інші літературні джерела, навчитись описувати класи, засвоїти способи створення об’єктів.
  2. При розробці програми використати знання, отримані під час вико­нання лабораторних робіт: №7 (розробка меню),  №9 (багато­файлові програми), №10 (сортування і пошук).
  3. Підготувати звіт з  лабораторної роботи, у якому представити такі матеріали:
    •  зміст завдання і варіант;
    •  лістинг програми.
    •  схему ієрархії класів програмного результати виконання – вигляд екрану при виконанні програми;
    •  результати роботи розробленого програмного засобу;
    •  висновки.

 

 

images (60).jpg

 

Варіанти індивідуальних завдань

 

Завдання 1.  Створити клас для обробки записів бази даних у відповід­ності з вказаною предметною областю. Розробити програму, дотримуючись таких вимог:

  1. Розмістити інтерфейс класу у заголовочному файлі, а визначення функцій та головну функцію програми – у двох окремих файлах.
  2. Передбачити можливість роботи з довільним числом записів, а також реалізувати окремими функціями класу: 
    •  конструктори без параметрів та з параметрами;
    •  додавання об’єктів;
    •  знищення об’єктів;
    •  виведення інформації на екран;
    •  пошук потрібної інформації за конкретною ознакою;
    •  редагування записів;
    •  сортування за різними полями. 
  3. При розробці програми слід здійснити захищення даних (опис з моди­фікатором private) для ізоляції елементів-даних класу від підпрограм, в яких цей клас використовується.
  4. Програма повинна містити меню для перевірки всіх методів класу. Бажано для реалізації меню розробити окрему функцію, яка повертає номер вибраного пункту меню.

 

 

Предметна область Реквізити об’єкту Параметр сортування Параметр пошуку
1. Бібліотека  інвентарний номер, автор, назва, кількість сторінок, рік видання Рік видання Автор
2. Телефонний довідник Прізвище, ім'я, по батькові, домашня адреса, телефон. Телефон Прізвище
3. Розклад руху літаків Номер рейсу, тип літака, напрямок руху, періодичність вильоту. Номер рейсу Тип літака
4. Колекція компакт-дисків Інвентарний номер, назва альбому, об'єм диску, тип, дата запису. Дата запису Назва альбому
5. Записна книжка Прізвище, ім'я, домашня адреса, телефон, електронна пошта. Прізвище Електронна пошта
6. Предметний покажчик Слово; номера сторінок, де це слово зустрічається; кількість цих слів на даній сторінці Номер сторінки Слово
7. Розклад пар Номер пари, предмет, прізвище викладача, форма заняття. Предмет Номер пари
8. Список файлів  ім'я файла, розширення, розмір, дата створення, атрибути. Розширен­ня Дата створення
9. Архів програм Назва програми, операційна система, розмір програми, дата запису           Назва програми Операційна система
10. Рахунки банку Прізвище, ім'я, дата останньої операції, сума вкладу Сума вкладу Дата операції
11. Користувачі локальної мережі Прізвище, група, обліковий запис, тип облікового запису. Тип облікового запису Прізвище
12. Камера схову Прізвище, дата здачі, термін зберігання, інвентарний номер та назва предмета Інвентар­ний номер Дата здачі
13. Склад товарів  інвентарний номер, назва товару, вага, ціна, кількість Вага Назва товару
14. Каса продажу квитків Назва пункту, час відправлення, дата відправлення, час прибуття, дата прибуття, ціна квитка Час від­правлення Назва пункту
15. Успішність студентів Прізвище, номер групи, оцінки з трьох предметів Прізвище Номер групи

 

Завдання 2. Утворити похідний клас, залучивши до нього як мінімум два додаткових поля таким чином, щоб клас набув більшої спеціалізованості. Для похідного класу використати кон­структор, щоб він містив усі аргументи, необхідні для ініціалізації об'єкту похідного класу. Створити додаткові необхідні функції, що дозволяють перевірити роботу похідних класів.

 

ask5-1

 

Контрольні питання

 
  1. Що таке об’єктно-орієнтоване програмування?
  2. Яка різниця між об'єктно-орієнтованним та функціональним програму­ванням?
  3. Що таке класи? Який синтаксис їх опису?
  4. Що таке об’єкти та екземпляри класу?
  5. Які основні принципи в об’єктно-орієнтованому програмуванні? Назвіть їх і дайте коротку характеристику сутностей цих принципів.
  6. Наведіть приклад опису будь-якого класу та приклад створення екземпляру цього класу.
  7. Для чого потрібні set- і get-функції?
  8. Які специфікатори доступу використовуються в описах класів? Поясніть їх значення.
  9. Дайте поняття закритих полів і методів класу.
  10. Що таке конструктори і деструктори класу? Для чого їх викорис­то­вують?
  11. Які особливості конструкторів у класах?
  12. Які особливості деструкторів у класах?
  13. Поясніть на прикладах сутність успадкування класів.
  14. Наведіть синтаксис опису успадкованого класу. Поясніть на прикладах.
  15. Що Ви можете сказати про модифікатори доступу в успадкованих класах?
  16. Як успадковуються конструктори у похідних класах?
  17. Які аиди успадкування Ви знєте? На ведіть приклади.
  18. Що таке віртуальні функції? Наведіть приклади використання.
  19. Що таке дружні функції і дружні класи?