Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекцій по С.doc
Скачиваний:
1
Добавлен:
01.04.2025
Размер:
8 Мб
Скачать
☆

6.2 Відкрите, закрите і захищене успадкування, успадкування типу і успадкування реалізації; абстрактні класи

Відкрите, закрите і захищене успадкування, успадкування типу і успадкування реалізації; абстрактні класи

Закрите успадкування частково вирішує проблему

class BoundedStack : private IntArray

Тепер всі відкриті і захищені методи суперкласу IntArray стануть закритими

методами класу BoundedStack . Попередній запис s.size() стане тепер неможливим.

Доводиться або знову делегувати функцію

int BoundedStack::size() const

{return IntArray::size();}

або знову користуватись засобами порушення прав доступу, схожими на дружні

функції.

class BoundedStack: private IntArray

{

. . . . . . . . .

public:

//відкривання окремої функції

using IntArray::size;

. . . . . . . . .

}

Цей тип успадкування називають закритим . Закрите успадкування дає

підкласу доступ до своєї захищеної і відкритої частин, але не делегує відкриту

частину до інтерфейсу підоб'єкту. Тепер стало зрозумілим, чому при перших прикладах

успадкувань писали public . Ці успадкування були відкритими . Права

доступу ті ж самі, але відкрита частина підоб'єкту тепер складається з власної

відкритої частини, доповненої відкритою частиною супероб'єкту. Тому кажуть,

що при відкритому успадкування успадковується тип супероб'єкту (власне його

інтерфейс), а при закритому успадкуванні — лише реалізація супероб'єкту.

Закрите успадкування закриває в батьківському класі все, відкрите відкриває

все, що можна відкрити. Існує ще один проміжний спосіб успадкування — захищене ( protected ).

Захищена частина суперкласу залишається захищеною, а не закритою, в підкласі.

class BoundedStack: protected IntArray

{

private:

static const int bos; //bottom of stack

protected:

int _top;

. . . . . . . . .

}

Клас PeekbackStack матиме доступ до захищених частин BoundedStack і IntArray

. При цьому в інтерфейс PeekbackStack потраплять всі відкриті методи BoundedStack

.

class PeekbackStack : public BoundedStack

{

public:

PeekbackStack(int size):BoundedStack (size){};

bool PeekbackStack::peekback(int, int&) const;

};

Ось реалізація

bool PeekbackStack::peekback(int index, int& value) const

{

if (empty())

throw BadStack();

// захищений атрибут BoundedStack

if (index<0||index>_top)

{

// захищений метод IntArray

value=ia[_top];

return false;

}

value=ia[index];

return true;

Тепер ми скажемо, що обмежений стек з підгляданням — це звичайний обмежений

стек, доповнений методом підглядання. Обидва вони реалізовані на базі обмеженого

масиву.

Корисно реалізувати декілька типів даних на базі інших. Наприклад, стек на

базі списку, черга на базі циклічного масиву. Зробіть це самостійно.

Уявімо собі, що у нашому розпорядженні є декілька стеків, наприклад, обмежений

стек на базі масиву і необмежений стек на базі списків. Ми розв'язуємо задачу,

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

на свої підкласи

template

class Stack

{

public:

Stack();

virtual bool empty() const=0;

virtual const T& top() const=0;

virtual void pop()=0;

virtual void push(const T& value)=0;

};

Такі класи називаються абстрактними, або чисто інтерфейсними класами. Клас

обмеженого стеку доведеться трохи підправити, оскільки в абстрактному класі

ми передбачили передачу параметрів і результатів вільну від копіювання, а тому

чисті типи замінені gсевдонімами

class BoundedStack: public Stack<int>, protected IntArray

{

private:

static const int bos; //bottom of stack

protected:

int _top;

public:

class BadStack{};

explicit BoundedStack(int size);

bool empty() const;

bool full() const;

const int& top() const;

void pop();

void push(const int& value);

};

Функція size() для об'єктів типу Stack стала недоступною, оскільки вона була

успадкована підкласом з іншого батьківського класу. При необхідності її появи

в інтерфейсі

int BoundedStack::size() const

{return IntArray::size();}