Наследуй правильно
Виды наследования
Наследование реализации (inheritance of implementation)
Priority Queue is-a Queue?
Is-a относится к поведению, а у обоих очередей разное поведение…
А что на практике в Java?
Сложный выбор между наследованием и агрегацией
Пример выбора решения (C++)
Расширение поведения наследованием
Расширение поведения агрегацией
Новые варианты
Cкрытие каких-то методов (если is-a не нужно)
Наследование: когда нужно отношение is-a по ПОВЕДЕНИЮ
Агрегация и композиция: has-a и holds-a
Inheritance vs Aggregation
Замечания
⚙️ has-a — композиция
А как же доступ к защищенным полям при агрегации?
Reuse у наследования тоже довольно ограничен
Виды дизайна классов
Наследование и агрегация – ключевые блоки ООД
1.95M

4. Наследуй правильно

1. Наследуй правильно

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

• Наследование интерфейса (inheritance of
interface) – “чистая” (pure) форма, когда
наследник сохраняет и, возможно, расширяет
родительский интерфейс.
• Полностью соблюдаются все ожидания при
работе через родительский интерфейс при
замещении (substitution) таким наследником.
• Наследник обеспечивает лишь расширение
функциональности родителя.
• Термин “is-a” относится именно к поведению
родителя (принцип LSP в SOLID).

3.

4. Наследование реализации (inheritance of implementation)

• Наследование происходит лишь
для выделения общего кода
(reuse)
• Некоторые методы родителя могут
быть переопределены, нарушив
предположения о родителе.
• Наследник не является во всех
ситуациях родителем (Not Is-a)!

5. Priority Queue is-a Queue?

• Очередь Queue – контейнер,
обеспечивающий доступ к элементам
в порядке First In – First Out
• Очередь с приоритетом Priority Queue –
обеспечивает выдачу элементов в
заданном порядке
• Одинаковый набор операций:
enqueue(obj) // положить элемент
obj = dequeue() // выдать элемент
clear() // удалить все элементы
• Корректно ли унаследовать Priority Queue от Queue?

6. Is-a относится к поведению, а у обоих очередей разное поведение…

• Лучше их сделать
братьями
• Формулируем общий
интерфейс, или
выносим общий код в
абстрактный класс и
делаем двух
наследников

7. А что на практике в Java?

• Collection – набор методов для обхода и
работы с любой коллекцией
• Deque – интерфейс двунаправленной
очередь, где элементы можно вставлять и
забирать с обоих концов
• LinkedList – реализация в виде связного
списка элементов (медленный, но
неограниченный)
• ArrayDeque – реализация дэка на
массивах (быстрый, но ограниченный по
размеру)

8. Сложный выбор между наследованием и агрегацией

• Агрегация (has-a, holds-a):
+ Reuse открытых методов
целевого класса
+ Гибкая динамическая связь
• Наследование:
+ Лаконичный reuse кода
родителя
+ Доступ к его защищенным
данным
+ Замещение родителя (is-a)
- Самая сильная статическая связь
между классами

9. Пример выбора решения (C++)

10. Расширение поведения наследованием

11. Расширение поведения агрегацией

12. Новые варианты

13. Cкрытие каких-то методов (если is-a не нужно)

14. Наследование: когда нужно отношение is-a по ПОВЕДЕНИЮ

15. Агрегация и композиция: has-a и holds-a

16. Inheritance vs Aggregation

Отношение
Тип связи
Кто создаёт объект
Жизненный цикл
Можно разделять?
✅ Да, может использоваться
несколькими объектами
holds-a
Агрегация (слабая)
Внешний код (извне передаётся в
конструктор)
Независим
has-a
Композиция (сильная)
Сам владелец (new внутри)
Связан: уничтожается вместе
❌ Нет, уникален для каждого
с владельцем
is-a
Наследование
(сильнейшая)
Circle : Shape
Определяется на этапе
проектирования
Ключевая фраза
«Студент держит калькулятор»
«Студент имеет личный
калькулятор»
Базовый живёт внутри потомка Круг наследует фигуру

17. Замечания

• Наследование увеличивает связность классов друг с другом
• Оптимально в случаях, когда требуется замена родителя и
расширение его поведения
• В большинстве других случаев предпочитают агрегацию из-за
гибкой замены целевого объекта и наличия контроля за ним.

18.

English     Русский Rules