Similar presentations:
5_Абстракции,_полиморфизм_и_множественное_наследование
1. 5. Абстракции, полиморфизм и множественное наследование
2. Виды дизайна классов
• Конкретный (concrete), запрещает наследование: String,ComplexNumber
• Абстрактный (abstract), корень иерархии: Animal
• Узловой (node), промежуточный в иерархии: Crocodile
• Адаптер (adapter) – адаптирует поведение нужного класса
3. Конкретный класс
• Отображает простую и понятную концепцию: строка, вектор, дата,комплексное число, структуры…
• Имеет реализацию всех методов
• Подобные классы, если используются во многих задачах, встраиваются
в язык или библиотеки
• Автономны
• Рекомендуется запретить наследование:
• Чтобы не нарушить поведением наследников его четкую концепцию
• В целях производительности
• Запретить доступ к “чувствительным” данным
• Запрет переиспользования реализации класса третьей стороной
4. Почему sealed или final (Java, C++) имеет смысл?
Рекомендация: если класс несконструирован специально для
наследования, запретите его.
5. Абстрактный класс
6. Полиморфизм – способность иметь много форм (is-a): Фигура имеет много форм – круг, квадрат и т.п., но сама по себе фигура – это
абстракция• Конструкторы
нужны для
инициализации
полей
наследниками
• Их нельзя
вызвать из
другого кода
• Делайте их
protected!
7. Пример 100% необходимости полиморфизма: Гетерогенные (Heterogenous) коллекции
Коллекции, которые хранят элементы с общим предкомShape[] shapes = new Shape[2];
shapes[0] = new Square(200, 200);
shapes[1] = new Circle(300, 300);
foreach (Shape shape in shapes)
shape.Draw();
8. Приведение к предку (Up-casting)
• Shape s = new Circle(100, 100);При этом s будет содержать ссылку на
объект типа Circle.
s.Draw() => Drawing a CIRCLE at 100,100
• Всегда производится неявно (implicit),
статически и безопасно (Circle ведет
себя как Shape)
9. Разница между override и new методами
New сообщает, что полиморфизм надо “отключить”s.Draw() => Drawing a SHAPE at 100,100
10. Явное приведение типа (Down-casting)
• Имея ссылку на родителя, как обратится к методам наследника?• Принудительно приводим объект к классу наследника во время
выполнения
• Не безопасно (unsafe), т.к. приводимый объект может быть не из
этой иерархии, а ошибка будет только во время выполнения
11. Наследование и агрегация – ключевые блоки ООД
Пример паттернАдаптер
https://www.bestprog.net/r
u/2020/09/24/patternsexamples-ofimplementation-of-theadapter-pattern-in-c-ru/
12. Адаптер через наследование, или через агрегацию
• Клиент сформулировалсвои требования к
удаленной системе в
виде интерфейса
ITarget. Работа через
него - упрощает
клиента.
• Удаленная система
реализована в виде
класса Adaptee. Он
непохож на ITarget.
• Нужен класс-адаптер
13. Множественное наследование
• Класс наследует от нескольких родителей• Предпочтительно, чтобы родители были ортогональны друг другу
(без одинаковых методов)
• Удобно, когда разным клиентам нашего класса нужна разная
функциональность
• Удобно для reuse
• Усложняет код:
• В одном классе смешивается несколько обязанностей
• Один класс зависит от нескольких других
• Пересечение методов
14. Проблемы множественного наследования классов в С++
• getAge() – вызываетнеоднозначность
(ambiguity)
• Нет правил приоритета
родителей, поэтому
наследник должен сам явно
определить свой getAge()
15. Избыточность (Redundancy)
• Student содержит часть отPerson
• Employee содержит часть от
Person
• StudentEmp содержит часть от
двух Person
16. И снова неоднозначность
Student меняетреализацию метода
родителя, а Employee
нет
17. C++ имеет костыль “виртуальное наследование”
• Еслинаследование
родителей
отмечено virtual,
то их общий
наследник не
наследует
двойную копию
прадеда
• Но такая отметка
ставится только
постфактум,
когда проблема
уже проявилась,
заранее ее не
предугадать!
18.
19. Интерфейсы C# и Java
• Помогают наследоватьразноплановое поведение
• Лишены проблем с
наследованием
реализации и данных
• Удачная альтернатива
множественному
наследованию
https://dotnettutorials.net/les
son/multiple-inheritancerealtime-example-in-csharp/
20. Интерфейсы C# 8.0
• Имеют реализацию методов поумолчанию
• Отличаются от абстрактных классов
отсутствием полей и конструкторов
• Нужны для расширения старых
интерфейсов
https://dev.to/lolle2000la/why-interface-defaultimplementations-in-c-are-a-great-thing-52nj
programming