Получить доступ

Почему java.util.Stack, унаследованный от Vector, считают ошибкой дизайна?

MiddleООП
Коротко

«Стек — это вектор» неверно: наследование выставило наружу get(i), add(i, x), remove(i) — операции, разрушающие инвариант LIFO. Правильно — композиция: список внутри, наружу только push, pop, peek.

  • Наследование — «является», и подтип получает весь контракт родителя
  • Плюс лишняя синхронизация от Vector
  • В новом коде — Deque и ArrayDeque

А ещё Тот же пример у Блоха: Properties extends Hashtable

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Наследование означает «является», и подтип обязан быть подставим вместо базового типа со всеми его операциями. Здесь же клиент, получивший Stack, вправе вызвать get(0), add(2, x) или remove(5) — стек перестаёт быть стеком. Правильное решение — композиция: держать список внутри и выставить только push, pop и peek, то есть ровно те операции, которые сохраняют инвариант. Это и есть смысл правила «композиция вместо наследования»: наследование переиспользует код ценой жёсткой связи и раскрытия чужого контракта. Отсюда же и совет использовать ArrayDeque вместо Stack в современном коде.

Что хотят услышать

  • Почему наследование здесь ошибочно.
  • Композиция как решение.

Частые ошибки

  • Наследоваться ради переиспользования кода там, где отношения «is-a» нет.
  • Считать проблему только в производительности синхронизированного Vector.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Наследование протащило в контракт стека методы доступа по индексу и вставки в середину, которыми можно нарушить дисциплину LIFO
  • ✗Vector работает медленнее, чем ArrayList
  • ✗Stack не реализует интерфейс Collection
  • ✗У Stack нет метода push

Что спросят дальше

  • Как связаны эта ошибка и принцип подстановки Лисков?
  • Что такое проблема хрупкого базового класса?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем