You are on page 1of 47

Об’єктно-орієнтоване

програмування
Максим Михайлович Древаль
m.dreval@kpi.ua

Кафедра математичних методів системного аналізу (ММСА)


Інститут прикладного системного аналізу
НТУУ «КПІ ім. І.Сікорського»

Весняний семестр 2020/21


Старт курсу — 06 лютого 2021

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 1
У попередній серії…

➢ Діаграма класів

➢ Скорочена та аналітична форми

➢ Загальна нотація класу

➢ Відношення на рівні об’єктів: проста асоціація, агрегація, композиція

➢ Відношення на рівні класів: спадкування, реалізація

➢ Віртуальні та чисто віртуальні методи

➢ Абстрактний клас та клас-інтерфейс

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 2
Нагадування

Види відношень в об’єктно-


орієнтованих моделях

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 3
Відношення (асоціації)

➢ В об’єктно-орієнтованій моделі об’єкти взаємодіють між собою

➢ Зазвичай об’єкт «надає послуги» кільком іншим об'єктам

➢ Об’єкт має зв’язки з іншими об'єктами для делегування завдань

Види відношень

на рівні об’єктів на рівні класів загальні

проста асоціація спадкування залежність


агрегація реалізація уточнення
композиція

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 4
Проста асоціація

➢ «Найслабший» вид відношення між об’єктами

➢ Характеризує, що один об’єкт може взаємодіяти з іншим об’єктом

➢ Зазвичай називається просто «асоціацією»

Види простої асоціації

за напрямком за кратністю

одностороння бінарна
двостороння тернарна
n-арна

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 5
Одностороння асоціація

➢ Зв’язок встановлюється лише в одному напрямку

➢ Позначається стрілкою до «обслуговуючого» об’єкта

lives in
Alice House
1 1

“Alice lives in a house”

drives
Alice Car
1 *

“Alice drives her car”

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 6
Двостороння асоціація

➢ Зв’язок встановлюється в обох напрямках

➢ Позначається суцільною лінією між об’єктами

works for
Employee Company
* 1

“Employee works for company”


“Company employs employees”

friend
Alice Bob
1 1

“Alice is Bob’s friend”


“Bob is Alice’s friend”

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 7
Бінарна асоціація

➢ Асоціює об’єкти рівно двох класів

➢ Позначається суцільною лінією або стрілкою між об’єктами

works for
Employee Company
* 1

Асоціація «works for» пов’язує об’єкти рівно двох класів

drives
Alice Car
1 *

Асоціація «drives» пов’язує об’єкти рівно двох класів

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 8
Тернарна асоціація

➢ Асоціює об’єкти рівно трьох класів

➢ Позначається ромбом, який з’єднується лініями з пов’язаними об’єктами

Student Teacher
* 1

*
Course

Тернарна асоціація пов’язує об’єкти рівно трьох класів

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 9
n-арна асоціація

➢ Зазвичай — асоціація між об’єктами трьох або більше класів

➢ Практичні приклади достатньо рідкісні, за можливості розкладається на


простіші асоціації

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 10
Агрегація та композиція

➢ Відношення типу «частина-ціле»

Head
1

Arm Alice Leg


2 2

Body

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 11
Дружні функції та класи

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 12
Дружні функції
Приклад

class X {
int a, b;
public:
void memberFunction();

}

➢ Глобальна функція:

void doSomething (X obj) {


obj.a = 3; // Error
obj.b = 4; // Error
}

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 13
Оголошення дружніх функцій
➢ Для того, щоб отримати доступ до захищених членів класу X, функція
doSomething() має бути оголошена дружньою функцією.

class X {
int a, b;
public:

friend void doSomething (X obj);
}

➢ Тепер глобальна функція матиме доступ до захищених членів класу X:

void doSomething (X obj) {


obj.a = 3; // OK
obj.b = 4; // OK
}

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 14
Оголошення дружніх функцій
➢ Сигнатури дружніх функції розміщуються в оголошенні класу

➢ Дружні функції не є членами класу

➢ Специфікатори доступу не впливають на оголошення дружніх функцій


або класів, тому їхні сигнатури можуть розміщуватися будь-де в
оголошенні класу

class X {

private:
friend void doSomething (X obj);
public:
friend void doAnything (X obj);

};

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 15
Визначення дружніх функцій

➢ У визначенні дружньої функції ключове слово friend не використовують

friend void DoSomething (X obj) {



}

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 16
Дружні класи

➢ Один з класів можна оголосити дружнім класом для іншого класу

class X {
friend class Y;

};

➢ Методи класу Y тепер матимуть доступ до захищених членів класу X

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 17
Оголошення дружніх класів

Приклад

class X {
friend class Y;
private:
int x_var1, x_var2;

};

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 18
Визначення дружніх класів

class Y {
private:
int y_var1, y_var2;
X objX;
public:
void setX() {
objX.x_var1 = 1;
}
};

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 19
Використання дружніх класів

int main() {
Y objY;
objY.setX();
return 0;
}

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 20
Спадкування.
Види спадкування в C++

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 21
Спадкування
Спадкування (наслідування) — це властивість ієрархічної
системи, яка дозволяє описати новий клас на основі вже
існуючого з частково або повністю запозиченим функціоналом.

➢ Спадкування реалізує зв’язок «is a» («is a kind of»)

➢ Наприклад:
➢ папуга є птах;
➢ долар є різновидом валюти;
➢ банк не є банківським рахунком.

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 22
Базові та похідні класи

➢ Якщо клас B успадковується від класу A, то B містить усі складові


(структуру інформації та поведінку) класу A

➢ Батьківський клас називається базовим (суперкласом), клас-нащадок —


похідним (субкласом)

➢ Окрім успадкованих характеристик, похідний клас може мати свої


унікальні характеристики

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 23
Спадкування

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 24
Застосування спадкування

#include <iostream>
using namespace std;
class Electronic {
public:
int serial_number = 12345678;
void turn_on() {
cout << "Electronic is on" << endl;
}
private:
int pincode = 87654321;
};

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 25
Застосування спадкування

class Phone: public Electronic {



};

int main() {
Phone Myphone;
Myphone.turn_on();
cout << "Serial number is: " <<
Myphone.serial_number << endl;
return 0;
}

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 26
Спадкування на діаграмах класів

Parent Class Base Class Superclass

Child Class Derived Class Subclass

UML-нотація

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 27
Види спадкування: public

public

➢ Public-члени базового класу стають public-членами похідного класу

➢ Private-члени базового класу не доступні за межами базового класу,


навіть у похідному класі (information hiding — приховування інформації)

Вид Специфікатор доступу у базовому → похідному класі


спадкування public protected private
public public protected hidden

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 28
Види спадкування: protected

protected

➢ Protected-спадкування може використовуватися для побудови ієрархії


класів за допомогою відношення «implemented in terms of»

➢ Якщо B є базовим класом, а D є похідним класом, то відкриті та захищені


члени B можуть використовуватися функціями-членами похідних від D
класів та їх друзями

Вид Специфікатор доступу у базовому → похідному класі


спадкування public protected private
protected protected protected hidden

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 29
Види спадкування: protected
Приклад

GrandParent

Parent

Child

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 30
Види спадкування: protected
class GrandParent {
public:
void doSomething();
};

class Parent: protected GrandParent {


void someFunction(){
doSomething();
}
};

class Child: protected Parent {


public:
Child() {
doSomething();
}
};
Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 31
Види спадкування: protected
➢ Якщо B є базовим класом, а D є похідним класом, то лише члени D, його
друзі та члени похідних від D класів можуть здійснити перетворення D* у
B* або D& у B&

void doSomething (GrandParent&);

class GrandParent { … };

class Parent: protected GrandParent { … };

class Child: protected Parent {


public:
Child()
{
doSomething(*this);
}
};
Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 32
Види спадкування: private
private

➢ Якщо вид спадкування не вказано, то за замовчуванням реалізується


private-спадкування

➢ Private-спадкування зазвичай використовується для побудови ієрархії


класів за допомогою відношення «implemented in terms of»

Вид Специфікатор доступу у базовому → похідному класі


спадкування public protected private
private private private hidden

class Child: private Parent { … };


// is equivalent to
class Child: Parent { … };

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 33
Види спадкування: private
Приклад

class Collection {

public:
void addElement(int);
bool searchElement(int);
bool searchElementAgain(int);
bool deleteElement(int);
};

➢ Якщо елемент не знайдено в Collection, метод searchElement() повертає


false

➢ searchElementAgain() знаходить друге входження елемента в Collection

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 34
Види спадкування: private

class Set: private Collection {



public:
void addMember(int);
bool isMember(int);
bool deleteMember(int);
};

void Set::addMember(int i) {
if (!isMember(i)) addElement(i);
}
bool Set::isMember(int i) {
return searchElement(i);
}

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 35
Види спадкування: private

➢ Тільки функції-члени похідного класу та його друзі можуть перетворювати


вказівник/посилання на об’єкт похідного класу у вказівник/посилання на
об’єкт базового класу

class Parent { … };
class Child: private Parent { … };

int main() {
Child cObj;
Parent *pPtr = &cObj; // Error
return 0;
}

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 36
Види спадкування: private

➢ Тільки функції-члени похідного класу та його друзі можуть перетворювати


вказівник/посилання на об’єкт похідного класу у вказівник/посилання на
об’єкт базового класу

void doSomething (const Parent&);

Child::Child() {
Parent& pPtr = static_cast<Parent&>(*this);
doSomething(pPtr);
// doSomething(*this);
}

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 37
Види спадкування: private

➢ Об’єкт похідного класу містить анонімний об’єкт базового класу

➢ За потреби можуть викликатися конструктор за замовчуванням та


конструктор копіювання базового класу

class Parent {
public:
Parent() {
cout << “Parent Constructor”;
}
Parent (const Parent& prhs) {
cout << “Parent Copy Constructor”;
}
};

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 38
Види спадкування: private
class Child: private Parent {
public:
Child() {
cout << “Child Constructor”;
}
Child (const Child& crhs) : Parent (crhs) {
cout << “Child Copy Constructor”;
}
};

int main() {
Child cObj1;
Child cObj2 = cObj1;
// Child cObj2(cObj1);
return 0;
}

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 39
Види спадкування: private

Результат виконання

Parent Constructor
Child Constructor
Parent Copy Constructor
Child Copy Constructor

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 40
Види спадкування: private
➢ У випадку private-спадкування похідний клас, який розташований нижче,
ніж на один рівень за ієрархією:
➢ не може отримати доступ до членів базового класу;
➢ не може перетворити вказівник/посилання на об’єкт похідного класу у
вказівник/посилання на об’єкт базового класу.

class GrandParent {
public:
void doSomething();
};

void doAnything (GrandParent&);

class Parent: private GrandParent {


void someFunction() { doSomething(); }
Parent() { doAnything (*this); }
};
Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 41
Види спадкування: private

class Child: private Parent {


public:
Child() {
doSomething(); // Error
doAnything(); // Error
}
};

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 42
Види спадкування

class B: public A {
class A { // x is public
public: // y is protected
int x; // z is not accessible from B
protected: };
int y;
class C: protected A {
private:
// x is protected
int z;
}; // y is protected
// z is not accessible from C
};
class D: private A { // private is default
// x is private
// y is private
// z is not accessible from D
};

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 43
Спеціалізація (обмеження)
➢ Спеціалізація (обмеження) — це вид зв’язку спадкування (нагадування:
встановлюється на етапі проектування), за якого похідний клас
поведінково несумісний з базовим класом, тобто базовий клас не завжди
може бути замінений похідним класом.

➢ Спеціалізація (обмеження) зазвичай реалізується за допомогою private-


або protected-спадкування.

Person
age : [0..125] age = a

setAge (a)

Adult if age < 18 then


age : [18..125] error
else
setAge (a) age = a

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 44
Спеціалізація (обмеження)

class Person {

protected:
int age;
public:
bool setAge(int _age) {
if (_age >=0 && _age <= 125) {
age = _age;
return true;
}
return false;
}
};

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 45
Спеціалізація (обмеження)

class Adult: private Person {


public:
bool setAge(int _age){
if (_age >=18 && _age <= 125) {
age = _age;
return true;
}
return false;
}
};

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 46
Далі буде… ☺

Об’єктно-орієнтоване програмування (2020/21) М.М. Древаль / ІПСА НТУУ «КПІ ім. І.Сікорського» // m.dreval@kpi.ua 47

You might also like