Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Поля (атрибути) та методи

Екземпляри класів або об' єкти.

Використання типів даних, визначених програмістом - одна з характерних рис структурного стилю програмування. Саме типізація відрізняє сучасні процедурні мови програмування (Модула, Паскаль, Сі, і т.д.) від своїх попередників. Тому визначення об' єкта як змінної деякого об' єктного типу є розвитком методології структурного стилю програмування.

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

Революційною ідеєю об' єктно - орієнтованої методології програмування є використання поняття спадкування як основного методу опису класів.

Під спадкуванням розуміють таке відношення двох класів (об' єктних типів), при якому одному з них (дочірньому) приписуються атрибути, властивості і методи іншого (батьківського).

У найбільш повному вигляді - у вигляді відкритого спадкування, якщо A і B - класи (об' єктні типи) і B успадковує A, це означає, що всі атрибути A, за означенням, є атрибутами B, і всі методи A, за означенням, є методами B.

При закритому спадкуванні клас В одержує від класу А в спадщину тільки виділену частину атрибутів і методів.

Клас A можна назвати класом-предком, B - нащадком. Наприклад, клас

((об' єктний тип) Людина може породити об' єктні типи Студент і Викладач. У цьому випадку говорять, що клас Студент (відповідно, Викладач) успадковує клас Людина.

 

Щоб похідні класи були не просто зручною формою короткого опису, в реалізації мови має бути вирішене питання: до якого з похідних класів відноситься об'єкт, на який дивиться покажчик base*? Існує три основні способи відповіді,:

[1] Забезпечити, щоб покажчик міг посилатися на об'єкти тільки одного типу ($$6.4.2);

[2] Помістити в базовий клас поле типу, яке зможуть перевіряти функції;

[3] використовувати віртуальні функції ($$6.2.5).

Покажчики на базові класи звичайно використовуються при проектуванні контейнерних класів (множина, вектор, список і так далі). Тоді у разі [1] ми отримаємо однорідні списки, тобто списки об'єктів одного типу. Способи [2] і [3] дозволяють створювати різнорідні списки, тобто списки об'єктів

декількох різних типів (насправді, списки покажчиків на ці об'єкти). Спосіб [3] - це спеціальний надійний в сенсі типу варіант способу [2]. Особливо цікаві і потужні варіанти дають комбінації способів [1] і [3].

Спочатку обговоримо простий спосіб з полем типу, тобто спосіб [2]. Приклад з класами manager/employee

можна перевизначити так:

struct employee {

enum empl_type { M, E };

empl_type type;

employee* next;

char* name;

short department;

//...

};

struct manager: employee {

employee* group;

short level;

//...

};

Маючи ці визначення, можна написати функцію, що друкує дані про довільного службовця,:

void print_employee(const employee* e)

{

switch (e ->type){

case E:

cout << e ->name << '\t' << e ->department << '\n';

//...

break;

case M:

cout << e ->name << '\t' << e ->department << '\n';

//...

manager* p = (manager*) e;

cout << "level" << p ->level << '\n';

//...

break;

}

}

Надрукувати список службовців можна так:

void f(const employee* elist)

{

for (; elist; elist=elist ->next) print_employee(elist);

}

Це цілком хороше рішення, особливо для невеликих програм, написаних однією людиною, але воно має істотний недолік: транслятор не може перевірити, наскільки правильно програміст поводиться з типами. У великих програмах це призводить до помилок двох видів. Перший - коли програміст забуває перевірити поле типу. Другий - коли в перемикачі вказуються не усі можливі значення поля типу. Цих помилок досить легко уникнути в процесі написання програми, але зовсім нелегко уникнути їх при внесенні змін в нетривіальну програму, а особливо, якщо це велика програма, написана кимось іншим. Ще важче уникнути таких помилок тому, що функції типу print() часто пишуться так, щоб можна було скористатися спільністю класів:

void print(const employee* e)

{

cout << e ->name << '\t' << e ->department << '\n';

//...

if (e ->type == M){

manager* p = (manager*) e;

cout << "level" << p ->level << '\n';

//...

}

}

Оператори if, подібні до приведених в прикладі, складно знайти у великій функції, що працює з багатьма похідними класами. Але навіть коли вони знайдені, нелегко зрозуміти, що відбувається насправді. Крім того, при всякому додаванні нового виду службовців потрібно зміни в усіх важливих функціях програми, тобто функціях, перевіряючих поле типу. В результаті доводиться правити важливі частини програми, збільшуючи тим самим час на відладку цих частин.

<== предыдущая лекция | следующая лекция ==>
Класи і їх опис в C++ | Конструктори і деструктори класів
Поделиться с друзьями:


Дата добавления: 2013-12-14; Просмотров: 612; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.01 сек.