Вопрос с собеседования · Java

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

MiddleООП
Коротко

«Стек — это вектор» неверно: наследование выставило наружу 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 минут бесплатно.

Разбор собеседования