Наследование и полиморфизм

42
1 3. Наследование и полиморфизм () Владислав Лавров, vlavrov.com Объектно-ориентированное программирование

Transcript of Наследование и полиморфизм

Page 1: Наследование и полиморфизм

1

3. Наследование и полиморфизм

() Владислав Лавров, vlavrov.com

Объектно-ориентированное программирование

Page 2: Наследование и полиморфизм

2

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

на основе существующих.

Класс, который наследуется, называется базовым, а класс, который наследует, —

производным.

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

Он наследует все переменные, методы и свойства, определяемые в базовом классе,

добавляя к ним свои собственные элементы.

Главное преимущество наследования — как только будет создан базовый класс, в

котором определены общие для множества объектов атрибуты, он может быть

использован для создания любого числа более конкретных производных классов. А в

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

классификация.

3.1. Основы наследования

() Владислав Лавров, vlavrov.com

Page 3: Наследование и полиморфизм

3

• Классическое, по типу «быть» («is-a»).

Основная идея – производные классы должны получать

функциональность от базового класса-предка и дополнять

ее новыми возможностями.

• Делегирование, по типу «иметь» («has-a»).

Назначение – объединить в производном классе для

взаимодействия друг с другом несколько независимых

классов.

3.2. Виды наследования

() Владислав Лавров, vlavrov.com

Page 4: Наследование и полиморфизм

4

Классическое наследование по типу «быть» («is-a»)

Пример. Теплопередача через многослойную огнеупорную стенку

q

a раб a

окр

окрt

рабt

q

S1

l1tпов.раб.

tпов.окр

t1-2

S2

l2

рабt

a раб

a окр

окрt

l1, l2

S1, S2

Rраб

q

Rcт1, Rcт2

Rокр

Расчет тепловых сопротивлений, температуры на границе слоев и

плотности теплового потока t1-2

Огнеупорный слой – это часть огнеупорной стенки

() Владислав Лавров, vlavrov.com

Page 5: Наследование и полиморфизм

5

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

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

() Владислав Лавров, vlavrov.com

Page 6: Наследование и полиморфизм

6

Классическое наследование по типу «быть» («is-a»)

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

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

Огнеупорный слой (LayerFlux) – это часть огнеупорной стенки (Wall)

() Владислав Лавров, vlavrov.com

Page 7: Наследование и полиморфизм

7

Реализация классического наследования по типу «быть» («is-a»)

() Владислав Лавров, vlavrov.com

Page 8: Наследование и полиморфизм

8

Пример реализации перегруженного метода в производном классе

() Владислав Лавров, vlavrov.com

Page 9: Наследование и полиморфизм

9

Наследование по типу «иметь» («has-a»)

() Владислав Лавров, vlavrov.com

Page 10: Наследование и полиморфизм

10

Пример реализации наследования по типу «иметь» («has-a»)

() Владислав Лавров, vlavrov.com

Page 11: Наследование и полиморфизм

11

3.3. Организация защищенного доступа

Защищенный член создается с помощью модификатора доступа protected.

Используя модификатор доступа protected, можно создать члены класса,

являющиеся закрытыми для своего класса, но все же наследуемыми и

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

Mодификатор доступа protected следует применять в том случае, если

требуется создать член класса, доступный для всей иерархии классов, но

для остального кода он должен быть закрытым.

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

свойством.

() Владислав Лавров, vlavrov.com

Page 12: Наследование и полиморфизм

12

Пример реализации защищенного доступа

Используем в наследуемом классе защищенные члены базового класса

() Владислав Лавров, vlavrov.com

Page 13: Наследование и полиморфизм

13

3.4. Ключевое слово sealed

Ключевое слово sealed исключает наследование.

Если класс помечен как sealed (запечатанный), компилятор не позволяет

наследовать от него.

Наследовать ClassA нельзя, т.к. он помечен как sealed

() Владислав Лавров, vlavrov.com

Page 14: Наследование и полиморфизм

14

Необходимость использования sealed

1. Класс или метод обеспечивает внутренние действия библиотеки,

класса или других разрабатываемых классов, поэтому любая

попытка переопределить некоторую его функциональность

приведет к нестабильности кода.

2. Коммерческие соображения, чтобы предотвратить использование

классов способом, противоречащим лицензионным соглашениям.

() Владислав Лавров, vlavrov.com

Page 15: Наследование и полиморфизм

15

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

Вопрос: Какой конструктор отвечает за построение объекта производного класса: конструктор базового класса, конструктор производного класса или же оба?

Ответ: Конструктор базового класса конструирует базовую часть объекта, а конструктор производного – производную часть этого объекта.

Используется ключевое слово base:

• во-первых, для вызова конструктора базового класса;

• во-вторых, для доступа к члену базового класса, скрывающегося за членом производного класса.

() Владислав Лавров, vlavrov.com

Page 16: Наследование и полиморфизм

16

Пример использования ключевого слова base

Вывод в консоль:«Координаты объекта: 1, 4, 5»

Вывод в консоль:«Новые координаты объекта: 10, 40, 50»

В конструкторе производного класса использовано слово base.

Поэтому будет вызван конструктор базового класса MyClass

() Владислав Лавров, vlavrov.com

Page 17: Наследование и полиморфизм

17

Пример Иерархия классов сотрудников

Производный классSalesPerson (Продавец)

Введено новое свойствоNumberOfSales (Число продаж)

Базовый класс Employee (Работник)

Производный классManagerPerson (Менеджер)

Введено новое свойствоNumberOfOptions (Число опционов)

() Владислав Лавров, vlavrov.com

Page 18: Наследование и полиморфизм

18

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

() Владислав Лавров, vlavrov.com

Page 19: Наследование и полиморфизм

19

Пример Проверяем новую функциональность производных классов

У продавца новое свойство – NumberOfSales (Число продаж)

У менеджера новое свойство – NumberOfOptions (Число опционов)

() Владислав Лавров, vlavrov.com

Page 20: Наследование и полиморфизм

20

Пример Более эффективно определение производных классов с помощью ключевого слова base

() Владислав Лавров, vlavrov.com

Page 21: Наследование и полиморфизм

21

Принципы действия ключевого слова base

• Когда в производном классе указывается ключевое слово base, то

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

• Ключевое слово base всегда обращается к базовому классу, стоящему в

иерархии непосредственно над вызывающим классом.

• Аргументы передаются базовому конструктору в качестве аргументов

метода base (аргументы).

• Если же ключевое слово отсутствует, то автоматически вызывается

конструктор, используемый в базовом классе по умолчанию.

() Владислав Лавров, vlavrov.com

Page 22: Наследование и полиморфизм

22

Полиморфизм предоставляет подклассу способ определения собственной

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

процесса, который называется переопределением метода (method overriding).

Виртуальным называется такой метод, который объявляется как virtual в

базовом классе. Виртуальный метод отличается тем, что он может быть

переопределен в одном или нескольких производных классах.

Вариант выполняемого виртуального метода выбирается по типу объекта,

а не по типу ссылки на этот объект.

3.6. Поддержка полиморфизма в C#. Виртуальные методы и свойства

() Владислав Лавров, vlavrov.com

Page 23: Наследование и полиморфизм

23

Пример Улучшить систему бонусов у продавцов и менеджеров

В базовом классе Employee методы GiveBonus и DisplayStats сделаем виртуальными

() Владислав Лавров, vlavrov.com

Page 24: Наследование и полиморфизм

24

Пример Для Продавца в производном классе переопределим расчет бонусов по новому алгоритму в зависимости от количества продаж

() Владислав Лавров, vlavrov.com

Page 25: Наследование и полиморфизм

25

Пример Для Менеджера в производном классе переопределим расчет бонусов: кроме денег он получит дополнительные опционы на акции

() Владислав Лавров, vlavrov.com

Page 26: Наследование и полиморфизм

26

Пример Проверяем новую функциональность производных классов

Переопределим метод DisplayStats() в классе ManagerPerson

Переопределим метод DisplayStats() в классе SalesPerson

() Владислав Лавров, vlavrov.com

Page 27: Наследование и полиморфизм

27

Абстрактный класс — это базовый класс, который не предполагает создания

экземпляров через вызов конструктора напрямую, но экземпляр

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

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

Для объявление используется ключевой слово abstract.

Ключевое слово abstract может использоваться с классами, методами,

свойствами, индексаторами и событиями.

3.7. Абстрактные классы

() Владислав Лавров, vlavrov.com

Page 28: Наследование и полиморфизм

28

Пример Использование абстрактного класса

………

………

В производном классе методы GiveBonus(…) и DisplayStats() обязательно надо переопределить

В базовом классе методы GiveBonus(…) и DisplayStats() объявлены как абстрактные. В наследуемых классах их обязательно надо переопределить

Класс Employee объявлен как абстрактный.Экземпляров создать нельзя.

() Владислав Лавров, vlavrov.com

Page 29: Наследование и полиморфизм

29

Возможности и ограничения абстрактных классов:

• Экземпляр абстрактного класса создать нельзя через вызов конструктора

напрямую, но экземпляр абстрактного класса создается неявно при

построении экземпляра производного конкретного класса.

• Абстрактные классы могут содержать как абстрактные, так и не

абстрактные члены.

• Неабстрактный (конкретный) класс, являющийся производным от

абстрактного, должен содержать фактические реализации всех

наследуемых абстрактных членов.

Абстрактные классы

() Владислав Лавров, vlavrov.com

Page 30: Наследование и полиморфизм

30

Возможности абстрактных методов:

• Абстрактный метод является неявным виртуальным методом.

• Создание абстрактных методов допускается только в абстрактных классах.

• Тело абстрактного метода отсутствует; создание метода просто

заканчивается двоеточием, а после сигнатуры ставить фигурные скобки ({ })

не нужно.

• Реализация предоставляется методом переопределения override, который

является членом неабстрактного класса.

Абстрактные методы

() Владислав Лавров, vlavrov.com

Page 31: Наследование и полиморфизм

31

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

Пример Иерархия классов геометрических фигур

() Владислав Лавров, vlavrov.com

Page 32: Наследование и полиморфизм

32

Пример Реализация базового класса геометрических фигур

Класс Shape объявлен как абстрактный, поэтому создание объектов (экземпляров) класса Shape запрещено.

На его основе могут быть созданы конкретные фигуры

() Владислав Лавров, vlavrov.com

Page 33: Наследование и полиморфизм

33

Пример Реализация производных классов геометрических фигур

В классе Circle метод Draw() не

замещен, поэтому он будет

перенаправлен к его реализации в

базовом классе Shape

В классе Hexagon метод Draw()

замещен, поэтому он будет

реализован в производном

() Владислав Лавров, vlavrov.com

Page 34: Наследование и полиморфизм

34

Пример Вывод реализации в консоль

() Владислав Лавров, vlavrov.com

Page 35: Наследование и полиморфизм

35

Пример Чтобы гарантировать, что каждый производный класс обязательно заместил метод Draw(), надо объявить его абстрактным в базовом классе Shape

() Владислав Лавров, vlavrov.com

Page 36: Наследование и полиморфизм

36

Пример В производном классе Circle метод Draw() теперь обязательно надо заместить

() Владислав Лавров, vlavrov.com

Page 37: Наследование и полиморфизм

37

Пример

Вывод реализации в консоль.

Теперь всегда известно кто создал фигуры, поскольку конкретная

реализация метода будет выбрана автоматически в зависимости от

того, для объекта какого класса был вызван этот метод.

() Владислав Лавров, vlavrov.com

Page 38: Наследование и полиморфизм

38

Пример Новая иерархия классов геометрических фигур: добавлен Oval (Эллипс)

3.9. Контроль версий членов класса: сокрытие методов

() Владислав Лавров, vlavrov.com

Page 39: Наследование и полиморфизм

39

Пример Реализация класса Oval с уникальной логикой метода Draw()

Чтобы реализовать полностью новый метод Draw(), отличный от метода

Circle.Draw(), при объявлении метода надо использовать ключевое слово new

() Владислав Лавров, vlavrov.com

Page 40: Наследование и полиморфизм

40

Пример

Проверим реализацию класса Oval с уникальной логикой метода Draw()

() Владислав Лавров, vlavrov.com

Page 41: Наследование и полиморфизм

41

Пример

Если надо, то можно для объекта класса Oval вызвать реализацию метода

Draw() из базового класса.

Это можно сделать – с помощью явного приведения типов.

() Владислав Лавров, vlavrov.com

Page 42: Наследование и полиморфизм

42

Когда использовать сокрытие метода?

Применяется в тех ситуациях, когда необходимо произвести

класс от базового класса, определенного в другой сборке NET.

Если метод в другой сборке несовместим с нашей

реализацией, то в производном классе надо сделать нашу

собственную реализацию метода с ключевым словом new.

() Владислав Лавров, vlavrov.com