Почему java.util.Stack, унаследованный от Vector, считают ошибкой дизайна?
«Стек — это вектор» неверно: наследование выставило наружу get(i), add(i, x), remove(i) — операции, разрушающие инвариант LIFO. Правильно — композиция: список внутри, наружу только push, pop, peek.
- Наследование — «является», и подтип получает весь контракт родителя
- Плюс лишняя синхронизация от Vector
- В новом коде — Deque и ArrayDeque
А ещё Тот же пример у Блоха: Properties extends Hashtable
Подробно
Наследование означает «является», и подтип обязан быть подставим вместо базового типа со всеми его операциями. Здесь же клиент, получивший Stack, вправе вызвать get(0), add(2, x) или remove(5) — стек перестаёт быть стеком. Правильное решение — композиция: держать список внутри и выставить только push, pop и peek, то есть ровно те операции, которые сохраняют инвариант. Это и есть смысл правила «композиция вместо наследования»: наследование переиспользует код ценой жёсткой связи и раскрытия чужого контракта. Отсюда же и совет использовать ArrayDeque вместо Stack в современном коде.
Что хотят услышать
- Почему наследование здесь ошибочно.
- Композиция как решение.
Частые ошибки
- Наследоваться ради переиспользования кода там, где отношения «is-a» нет.
- Считать проблему только в производительности синхронизированного Vector.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✓Через наследование в стек попали методы, ломающие LIFO
- ✗Vector синхронизирован, поэтому Stack работает медленнее, чем ArrayList
- ✗Stack не реализует интерфейс Collection
- ✗У Stack нет метода push
Что спросят дальше
- Как связаны эта ошибка и принцип подстановки Лисков?
- Что такое проблема хрупкого базового класса?
Разбор темы
- ООП и его принципы
Инкапсуляция, наследование, полиморфизм, абстракция — зачем они нужны, как работают внутри и почему композицию предпочитают наследованию.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.