Основы объектно-ориентированного программирования



              

Абстрактные предусловия


Правило ослабления предусловий может оказаться чересчур жестким в случае, когда наследник понижает уровень абстракции, характерный для его предка. К счастью, есть легкий обходной путь, полностью согласующийся с теорией.

Типичным примером этого является порождение BOUNDED_STACK от универсального класса стека (STACK). Процедура занесения в стек элемента (put) в порожденном классе имеет предусловие count <= capacity, где count - текущее число элементов в стеке, capacity - физическая емкость накопителя.

В общем понятии стека нет понятия емкости. Поэтому создается впечатление, будто при переходе к BOUNDED_STACK предусловие приходится усилить (от бесконечной емкости перейти к конечной). Как выстроить структуру наследования, не нарушая правило Утверждения Переобъявления?

Ответ становится очевиден, если мы ближе познакомимся с требованиями к клиенту. То, что нужно сохранить или ослабить, не обязательно является конкретным предусловием, как оно видится в реализации поставщика (реализация это его забота), но касается предусловия, как оно видится клиенту. Пусть процедура put класса STACK имеет вид:

put (x: G) is -- Поместить x на вершину. require not full deferred ensure ... end

где функция full всегда возвращает ложное значение, а значит, стек по умолчанию никогда не бывает полным.

full: BOOLEAN is -- Заполнено ли представление стека? -- (По умолчанию, нет) do Result := False end

Тогда в BOUNDED_STACK достаточно переопределить full:

full: BOOLEAN is -- Заполнено ли представление стека? -- (Да, если число элементов равно емкости стека) do Result := (count = capacity) end

Предусловие, такое как not full, включающее свойство, которое переопределяется потомками, называется абстрактным (abstract) предусловием.

Такое использование абстрактных предусловий для соблюдения правила Утверждения Переобъявления может показаться обманом, однако это не так. Несмотря на то, что конкретное предусловие фактически становится более сильным, абстрактное предусловие не меняется. Важно не то, как реализуется утверждение, а то, как оно представлено клиентам в интерфейсе класса (краткой или плоско-краткой форме).


Содержание  Назад  Вперед