Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
О.О.П / ооп / 18. Об'єктно-орієнтоване програмування, л.5.5 - 5.8.ppt
Скачиваний:
26
Добавлен:
30.05.2020
Размер:
3.38 Mб
Скачать

Публічне (відкрите) спадкоємство

Публічне спадкоємство - це

спадкоємство інтерфейсу (спадкоємство типа)

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

Похідний клас є підтипом батьківського

Похідний клас служить прикладом відношення «є» (is а)

Похідний клас є об'єктом батьківського

Приклади: «Собака є твариною», «Прямокутник

є замкнутою фігурою»

class CPerson

{

public:

std::string GetName()const; std::string GetAddress()const; int GetBirthYear()const;

private:

};

class CStudent : public CPerson

{

public:

std::string GetUniversityName()const; std::string GetGroupName()const; unsigned GetGrade()const; // год

обучения

};

class CWorker : public CPerson

{

public:

std::string GetJobPosition()const; int GetExperience()const;

};

CPerson

CStudent CWorker

Публічне спадкоємство як

спадкоємство

При публічному спадкоємстві клас-нащадок інтерфейсууспадковує інтерфейс батька

З об'єктами класу-спадкоємця можна звертатися так само як з об'єктами базового класу

Якщо це не так, то, ймовірно відкрите спадкоємство використовувати не слід

Покажчики і посилання на клас-нащадок можуть наводитися до покажчиків і послань на базовий клас

CShape

C2DShape C3DShape

CCircle

CTriangl

CCube

CSphere

e

 

 

 

void ProcessShape(CShape & shape)

{

...

}

 

void Test()

CCircle можна використовувати скрізь, де

{

CCircle circle;

використовується CShape

ProcessShape(circle);

Покажчик на похідний клас проводиться до

CShape * pShape = &circle; покажчика на базовий

}

CPoint

CCircle

CCylinder

Неправильний хід думок:

«Коло можна отримати, додавши до крапки радіус, а циліндр - додавши до кола висоту»

Неправильний контекст використання відкритого спадкоємства:

Відкрите спадкоємство повинне використовуватися не для того, щоб похідний клас міг використовувати код базового для реалізації

своєї функціональності

Клас-спадкоємець має бути окремим випадком

загальнішої абстрации

Тут:

Коло не є приватним випадком крапки Циліндр не є приватним випадком кола, і, тим більше, крапки

Приватне (закрите) спадкоємство

Приватне спадкоємство - це спадкоємство

реалізації

При приватному спадкоємстві відкриті і захищені поля і методи батьківського класу стають закритими полями і методами похідного

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

Похідний клас служить прикладом відношення «реалізований на основі» (implemented as)

Похідний клас реалізований на основі батьківського

Приклади: «Клас Stack реалізований на основі класу Array»

class CIntArray

{

public:

int operator[](int index)const; int& operator[](int index); int GetLength()const;

void InsertItem(int index, int value); private:

...

};

class CIntStack : private CIntArray

{

Не можна використовувати

public:

відкрите спадкоємство

void Push(int element);

•Стек не є масивом, але

int Pop();

bool IsEmpty()const;

користується реалізацією

};

масиву

•До стека не застосовні операції індексованого

Композиція - переважна

альтернатива приватному

спадкоємству

Замість спадкоємства реалізації у багатьох випадках може виявитися краще використовувати

композицію

При композиції новий клас може використовувати декілька екземплярів існуючого класу

Композиція робить класи менш залежними один від одного, чим спадкоємство

Можливі виключення, коли приватне спадкоємство є переважнішим

Необхідно дістати доступ до захищених методів існуючого класу

З точки зору інтерфейсу нового класу - відмінностей немає жодних

class CIntArray

{

public:

int operator[](int index)const; int& operator[](int index);

int GetLength()const;

void InsertItem(int index, int value); private:

...

};

class CIntStack2

{

public:

void Push(int element); int Pop();

bool IsEmpty()const; private:

CIntArray m_items;

};