Наследование

Содержание

Слайд 2

Наследование Наследование – это способ повторного использования кода, при котором новые

Наследование

Наследование – это способ повторного использования кода, при котором новые классы

создаются на базе существующих классов путем заимствования их элементов (данных и функций).
Новый класс объявляется наследником ранее определенного класса (базового класса).
Новый класс называют производным классом.
Производный класс может стать базовым для других классов.
Таким образом создается иерархия классов.
Слайд 3

Понятие наследования Наследование — важная составляющая концепции объектно-ориентированного программирования, благодаря которой

Понятие наследования

Наследование — важная составляющая концепции объектно-ориентированного программирования, благодаря которой возможно

создание новых классов на базе уже существующих.
Новые классы (производные) получают все элементы наследуемых классов (базовых).

Базовый класс

Производный класс

Слайд 4

Базовые и производные классы Наследование порождает иерархические древовидные структуры данных. В

Базовые и производные классы

Наследование порождает иерархические древовидные структуры данных. В них

всегда можно добавить новый класс в требуемом месте.

Polygon

Triangle

Quadrangle

Rectangle

Square

Rhombus

Parallelogram

IsoscelesTriangle

RightTriangle

Слайд 5

Простое и множественное наследования При простом наследовании производный класс имеет только

Простое и множественное наследования

При простом наследовании производный класс имеет только один

базовый класс. Базовый класс может иметь несколько производных классов. Иерархия классов имеет вид дерева.
При множественном наследовании производный класс имеет несколько родительских классов. Иерархия классов имеет вид ориентированного графа.

Базовый
класс

Производный
класс

Производный
класс

Базовый
класс

Производный
класс

Базовый
класс

Простое наследование

Множественное наследование

Слайд 6

Преимущества наследования 1) Повторное использование программ 2) Использование общего кода 3)

Преимущества наследования

1) Повторное использование программ

2) Использование общего кода

3) Согласование интерфейса

4) Программные

компоненты

5) Быстрое макетирование

Недостатки наследования

1) Скорость выполнения

2) Размер программ

3) Сложность программ

Слайд 7

сlass имя_производного_класса : атрибут_наследования имя_базового_класса { … };

сlass имя_производного_класса : атрибут_наследования имя_базового_класса { … };

Слайд 8

Спецификаторы доступа в ситуации без наследования

Спецификаторы доступа в ситуации без наследования

Слайд 9

Спецификаторы доступа в ситуации с наследованием Public — доступ открыт всем,

Спецификаторы доступа в ситуации с наследованием

Public — доступ открыт всем,

кто видит определение данного класса.
Protected — доступ открыт классам, производным от данного. То есть, производные классы получают свободный доступ к таким свойствам или метода. Все другие классы такого доступа не имеют.
Private — доступ открыт самому классу (т.е. функциям-членам данного класса) и друзьям (friend) данного класса - как функциям, так и классам. Однако производные классы не получают доступа к этим данным совсем. И все другие классы такого доступа не имеют.
Слайд 10

Наследование и доступ

Наследование и доступ

Слайд 11

Модификаторы наследования Атрибут наследования определяется тремя известными ключевыми словами: private, public

Модификаторы наследования

Атрибут наследования определяется тремя известными ключевыми словами: private, public и

protected, которые использовались для доступа к внутренним компонентам класса.

сlass имя_производного_класса : атрибут_наследования имя_базового_класса { … };

Слайд 12

Пример class Parent { public: int m_public; private: int m_private; protected:

Пример

class Parent
{
public:
int m_public;
private:
int m_private;
protected:
int m_protected;
};

class D2 : private

Parent  // закрытое наследование
{
// Закрытое наследование означает, что:
// члены public становятся private в дочернем классе;
// члены protected становятся private в дочернем классе;
// члены private недоступны для дочернего класса.
public:
int m_public2;
private:
int m_private2;
protected:
int m_protected2;
};
Слайд 13

Слайд 14

Особенности производного класса Обычно производный класс (ПК) содержит больше данных и

Особенности производного класса

Обычно производный класс (ПК) содержит больше данных и функций,

чем базовый класс (БК). Он наследует элементы БК и добавляет собственные.
ПК более специализирован, специфичен в своей области, представляет меньшее количество объектов.
Объект производного класса также является объектом базового класса. Но объект базового класса не является объектом производного класса.
В C++ возможны три вида наследования: открытое (public), защищенное (protected) и закрытое (private).
Слайд 15

Особенности производного класса В БК можно использовать спецификатор доступа protected. ПК

Особенности производного класса

В БК можно использовать спецификатор доступа protected.
ПК не

имеет прямого доступа к закрытым элементам БК.
ПК имеет прямой доступ к открытым и защищенным элементам БК.
Если у БК есть друзья, то производный класс их не наследует.
Слайд 16

Базовые и производные классы Синтаксис определения наследования: class Worker : public

Базовые и производные классы

Синтаксис определения наследования:
class Worker : public NSTUMember {


Класс может быть базовым прямо и косвенно:
Для Teacher прямым базовым классом является Worker, а косвенным – NSTUMember.

NSTUMember

Student

Worker

Administrator

Teacher

Scientist

Слайд 17

Наследование class Base { int x; public: void setX(int n) {

Наследование

class Base {
int x;
public:
void setX(int n) { x =

n; }
void showX() {cout << x << ' '; }
};
class Derived : public Base {
int y;
public:
void setY(int n) { y = n; }
void showY() {cout << y << ' '; }
};

int main() {
Base ob;
ob.setX(5);
ob.showX();
Derived od;
od.setX(10);
od.setY(20);
od.showX();
od.showY();
return 0;
}

Base

Derived

Слайд 18

Управление видимостью компонентов базового класса в производном Производный класс может получить

Управление видимостью компонентов базового класса в производном

Производный класс может получить доступ

к компонентам секций protected и public базового класса даже при самом жестком виде наследования private. Для этого используют квалификатор доступа <Имя класса>::<Имя компонента>. Квалификатор следует поместить в ту же секцию, в которой необходимый компонент был описан в базовом классе.
Слайд 19

Конструкторы и деструкторы при наследовании Правило вызова конструкторов и деструкторов при

Конструкторы и деструкторы при наследовании

Правило вызова конструкторов и деструкторов при одиночном

наследовании.
При создании экземпляра производного класса сначала выполняется конструктор базового, а затем производного класса.
Деструкторы выполняются в обратном порядке.
При создании объекта базового класса выполняются конструктор и деструктор только для данного базового класса.
Конструкторы производных и базового классов могут иметь аргументы.
Для того, чтобы осуществить передачу аргументов для конструктора базового класса необходимо воспользоваться следующей записью:

конструктор_производного_класса (аргументы) : конструктор_базового_класса (аргументы)

Слайд 20

Если конструкторы базовых классов не имеют аргументов, то производный класс может

Если конструкторы базовых классов не имеют аргументов, то производный класс может

не иметь конструктора. При наличии у конструкторов базового класса аргументов производный класс обязан иметь конструктор со списком инициализации следующего вида:
Слайд 21

Порядок работы конструкторов базового и производного классов.

Порядок работы конструкторов базового и производного классов.

Слайд 22

Наследование на примере класса «счетчик»

Наследование на примере класса «счетчик»

Слайд 23

Множественное наследование Язык С++ позволяет осуществлять наследование не только от одного,

Множественное наследование

Язык С++ позволяет осуществлять наследование не только от одного, но

и
одновременно от нескольких классов. Такое наследование получило название
множественного. Описание производного класса при множественном наследовании выглядит следующим образом:
Слайд 24

Наследование в С++ class A { ... }; class B {

Наследование в С++

class A
{
...
};
class B
{
...
};

Класс А

Класс В

Класс С

class C

: public A, public B
{
...
};

Ограничение доступа при наследовании

Слайд 25

Слайд 26

Множественное наследование class ScTeacher : public Teacher, public Scientist { …

Множественное наследование

class ScTeacher : public Teacher, public Scientist { …
class AdminTeacher

: public Teacher,
public Administrator { …

NSTUMember

Student

Worker

Administrator

Teacher

Scientist

ScTeacher

AdminTeacher

Слайд 27

Методы классов и множественное наследование В классе student содержатся сведения о

Методы классов и множественное наследование

В классе student содержатся сведения о

школе или университете, которые
за кончил студент, и об уровне
полученного им образования.
Информация об образовании нужна
только для ученых и менеджеров.
Слайд 28

Слайд 29

Слайд 30

Слайд 31

Пример. Наследование от двух базовых классов. В данном примере класс third

Пример. Наследование от двух базовых классов. В данном примере класс third

наследуется от классов first и second

Множественное наследование

Объект класса third состоит из следующих полей:
· поля num_f, унаследованного от класса first (описанного public, наследованного private, следовательно доступного private) и инициализированного случайным числом
· полей num_s и c_s, унаследованных от класса second (описанных public, наследованных public, следовательно доступного public) и инициализированных числами 50 и символом «R», причем инициализация поля c_s в конструкторе класса second не предусмотрена, поэтому она выполняется в теле конструктора класса third.

Слайд 32

Слайд 33

Конфликты при множественном наследовании class A1 { public: int a; void

Конфликты при множественном наследовании

class A1
{
public:
int a;
void Func();
};
class A2
{
public:
int

a;
void Func();
};
class B : public A1, public A2
{
...
};
void main()
{
B b;
b.a = 5; // Ошибка
b.Func(); // Ошибка
b.A1::a = 6; // Правильно
b.A1::Func(); // Правильно
b.A2::a = 7; // Правильно
b.A2::Func(); // Правильно
}

Для устранения конфликтов имен при множественном наследовании используется оператор расширения области видимости

Слайд 34

Неопределенность при множественном наследовании

Неопределенность при множественном наследовании

Слайд 35

сlass D { }; class B: public D { }; class

сlass D
{
};
class B: public D
{
};
class C: public D
{
};
class A: public B,

public C
{
};
Слайд 36

Пример. Проектирование классов с использованием наследования (классы Целое число и Вещественное

Пример. Проектирование классов с использованием наследования (классы Целое число и Вещественное

число).

Пусть требуется разработать классы для реализации объектов Целое число и
Вещественное число. Объект Целое число должен хранить длинное целое в десятичной записи и уметь выводить его значение. Объект Вещественное число должен хранить вещественное число, задаваемое в виде ccccc.dddddd, и его символьное представление.
Он также должен уметь выводить свое значение на экран. Для обоих объектов необходимо предусмотреть возможность инициализации как в
момент объявления переменной, так и в процессе функционирования. Поскольку вещественное число включает длинное целое как целую часть, класс для его реализации можно наследовать от класса, реализующего длинное целое число.

Наследование классов

Слайд 37

Слайд 38

Слайд 39

Виртуальное наследование Возможна ситуация, когда производный класс при наследовании от потомков

Виртуальное наследование

Возможна ситуация, когда производный класс при наследовании от потомков одного

базового класса многократно наследует одни и те же компоненты базового класса.
Иными словами, производный класс будет содержать несколько копий полей одного базового класса.

Многократное наследование полей базового класса

Слайд 40

Чтобы избежать многократного включения в производный класс компонентов базового класса, используется

Чтобы избежать многократного включения в производный класс компонентов базового класса, используется

виртуальное наследование. При виртуальном наследовании производный класс описывают следующим образом:

Виртуальное наследование

В этом случае включение в производный класс полей базового класса осуществляется один раз, а их инициализация выполняется в производном классе, который не является прямым потомком базового класса.
Вызов конструкторов при этом происходит в следующем порядке: сначала конструктор виртуально наследуемого базового класса, затем конструкторы базовых классов в порядке их перечисления при объявлении производного класса, за ними – конструкторы объектных полей и конструктор
производного класса.
Деструкторы соответственно вызываются в обратном порядке.
Виртуально наследуемый класс обязательно должен содержать конструктор без
параметров, который активизируется при выполнении конструкторов классов – прямых
потомков виртуально наследуемого класса.

Слайд 41

Виртуальное наследование. Реализуем иерархию классов. Класс derived наследуется от двух наследников

Виртуальное наследование.
Реализуем иерархию классов. Класс derived наследуется от двух наследников

класса fixed. Чтобы исключить удваивание полей, описанных в классе fixed, необходимо использовать виртуальное наследование.
Слайд 42

Включение: классы в классах Включение называют взаимоотношением типа «имеет». Мы говорим,

Включение: классы в классах
Включение называют взаимоотношением типа «имеет». Мы говорим,

что библиотека имеет книги (в библиотеке есть книги) или накладная имеет строки (в накладной есть строки). Включение также называют взаимоотношением типа «часть целого»: книга является частью библиотеки.
В ООП включение появляется, когда один объект является атрибутом другого объекта. Рассмотрим случай, когда объект класса A является атрибутом класса B:
Слайд 43

Включение: классы в классах Включение называют взаимоотношением типа «имеет». Мы говорим,

Включение: классы в классах
Включение называют взаимоотношением типа «имеет». Мы говорим,

что библиотека имеет книги (в библиотеке есть книги) или накладная имеет строки (в накладной есть строки). Включение также называют взаимоотношением типа «часть целого»: книга является частью библиотеки.
В ООП включение появляется, когда один объект является атрибутом другого объекта. Рассмотрим случай, когда объект класса A является атрибутом класса B:
Слайд 44

Слайд 45

Слайд 46

Слайд 47

Композиция: сложное включение Композиция — это более сложная форма объединения. Она

Композиция: сложное включение
Композиция — это более сложная форма объединения. Она

обладает всеми его свойствами, но имеет еще и такие, как:
♦ часть может принадлежать только одному целому;
♦ время жизни части то же, что и целого.
Слайд 48

Пример. Использование композиции для реализации включения объектов. Построим класс Вещественное число

Пример. Использование композиции для реализации включения объектов.

Построим класс Вещественное число на

базе класса Целое число, используя не наследование, а композицию.

В классе предусмотрим три конструктора:
· пустой без параметров – на случай создания неинициализированных объектов;
· инициализирующий – создает объект по записи числа;
· инициализирующий – создает объект, получая отдельно целую и дробную части
числа.

Слайд 49

Слайд 50

Среда разработки Microsoft Visual C++ . Работа с клавиатурой. При запуске

Среда разработки Microsoft Visual C++ . Работа с клавиатурой.

При запуске

вашей программы, главное окно должно будет выглядеть так
Слайд 51

Слайд 52

Связывание событий с элементами управления Свяжите код с событием WM_KEYDOWN клавиатуры.

Связывание событий с элементами управления
Свяжите код с событием WM_KEYDOWN клавиатуры. При

нажатии на клавишу будет появляться окно сообщения, которое будет показывать ее флаг.
Добавьте в функцию следующий код
Слайд 53

Параметры функции OnKeyDown: (UINT nChar, UINT nRepCnt, UINT nFlags) nChar -

 Параметры функции OnKeyDown:
(UINT nChar, UINT nRepCnt, UINT nFlags)  nChar - показывает код нажатой

клавиши.
nRepCnt - представляет число повторных нажатий на клавишу. Например, если вы долго удерживаете клавишу B, то этот параметр сохранит кол-во нажатий на эту клавишу.
nFlags представляет число нажатой специальной клавишы(такие как ALT, SHIFT).
Код, который объявляет три строки:
char strnChar[10]; char strnRepCnt[10]; char strnFlags[10];
Они будут хранить значения переменных nChar, nRepCnt, nFlags соответственно.
Функция itoa переводит число в текстовую строку.
Слайд 54

Слайд 55

Программа для пересчета из градусов в радианы.

Программа для пересчета из градусов в радианы.

Слайд 56

Добавим переменную, которая будет отвечать за «Поле редактирования».

Добавим переменную, которая будет отвечать за «Поле редактирования».

Слайд 57

Добавить #include "tchar.h"

Добавить #include "tchar.h"

Слайд 58

Слайд 59

Расположим на диалоговом окне следующие элементы три метки (Static Text) для

Расположим на диалоговом окне следующие элементы
три метки (Static Text)

для вывода заголовков полей;
три поля редактирования (Edit Control);
один элемент Group Box;
две радиокнопки (Radio Button) для выбора типа уравнения;
флажок (Check Box), определяющий как будет происходить вывод;
метку для вывода результатов;
кнопки для решения уравнения и выхода из программы;
Слайд 60

Определим переменные для полей редактирования, радиокнопок и флажка. Щелкаем правой кнопкой

Определим переменные для полей редактирования, радиокнопок и флажка. Щелкаем правой кнопкой

мыши по первому полю ввода, выбираем «Добавить переменную…». Заполняем окно так, как это сделано на скриншо-те.

Аналогично добавляем переменные для двух оставшихся полей (m_EditB, m_EditC).

Слайд 61

определение переменных для радиокнопок. Заходим в свойства элемента GroupBox и устанавливаем

определение переменных для радиокнопок. Заходим в свойства элемента GroupBox и устанавливаем

значение «Группа»->True. То же самое делаем и для обоих радиокнопок, после чего определяем имя и тип переменных для них (рис. ниже).
Слайд 62

Установка свойства Group в True была необходима для того, чтобы можно

Установка свойства Group в True была необходима для того, чтобы можно

было создать переменные как экземпляры класса RadioButton. Но если мы сейчас запустим программу, то переключения между кнопками не будет. Поэтому установим у второй радиокнопки свойство Group в True.

При работе с группой радиокнопок нужно установить у них свойство Group в True, после чего назначить переменные для всех кнопок, а затем установить у всех кроме первой значение False .

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

Слайд 63

Изменим значение ID четвертой метки (расположена над кнопкой «Решить») на IDC_STATIC1.

Изменим значение ID четвертой метки (расположена над кнопкой «Решить») на IDC_STATIC1.

Определим переменную, отвечающую за работу с этой меткой (рис. ниже).
Слайд 64

Переопределяем ID кнопки «Решить», впишем например ID_Solve. Щелкаем два раза левой

Переопределяем ID кнопки «Решить», впишем например ID_Solve.
Щелкаем два раза левой

кнопкой мыши по кнопке «Решить», и попадаем в окно с кодом. Тут подключаем библиотеку math.h, после чего вводим в функцию OnBnClickedSolve() следующий текст.