[x]. Предусловие задает область определения DOM функции r (подмножество I, на котором r гарантированно вырабатывает результат).

[x]. Постусловие задает для каждого x из DOM подмножество RESULTS(x) множества O, такое, что r (x) RESULTS (x). Так как постусловие не всегда однозначно описывает результат, это подмножество может иметь больше одного элемента.

Правило Утверждения Переобъявления означает, что повторное объявление может расширять область определения и сужать множество результатов. Пометив новые множества знаком ', запишем требования, закрепленные этим правилом:

DOM' DOM

RESULTS' (x) RESULTS (x) для всех x из DOM

Предусловие устанавливает, что подпрограмма и ее повторные объявления, как минимум, должны принимать некоторые входы (DOM), хотя повторные объявления могут это множество и расширить. Постусловие говорит, что результаты, возвращаемые подпрограммой и ее повторными объявлениями, могут, самое большее, содержать значения из RESULTS(x), однако, постусловия при повторных объявлениях могут это множество сузить.

В этом описании состояние системы в период выполнения определяется состоянием (значениями) всех достижимых объектов. Кроме того, входные состояния (элементы I) также включают в себя значения аргументов. Более подробное введение в математическое описание программ и языков программирования см. в [M 1990].

Глобальная структура наследования

Ранее мы уже ссылались на универсальные (universal) классы GENERAL и ANY, а также на безобъектный (objectless) класс NONE. Пришло время пояснить их роль и представить глобальную структуру наследования.

Универсальные классы

Удобно использовать следующее соглашение:

Правило Универсального Класса

Любой класс, не содержащий предложение наследования, неявно содержит предложение вида:

inherit ANY,

ссылающееся на класс ANY из библиотеки Kernel.

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

Для большей гибкости поместим эти компоненты в класс GENERAL, чьим потомком является ANY. Сам класс ANY по умолчанию не имеет никаких компонентов, будучи классом вида: class ANY inherit GENERAL end. При создании нового проекта его менеджер может решить, какие общие для проекта компоненты следует включить в класс ANY, в то время как GENERAL остается всегда неизменным.

Для построения нетривиального ANY можно прибегнуть к наследованию. В самом деле, класс ANY можно породить от некоторого HOUSE_STYLE или нескольких таких классов, не вводя циклы в иерархию наследования и не нарушая правило об универсальном классе: достаточно сделать класс HOUSE_STYLE и другие классы потомками GENERAL. Вынесенный на рис. 16.4 текст 'Классы разработчика' означает все классы, написанные разработчиком и не порожденные от GENERAL явным образом.

Рис. 16.4.  Глобальная структура наследования

Нижняя часть иерархии

На рис. 16.4 представлен также класс NONE, антипод класса ANY, потомок всех классов, не имеющих собственных наследников и превращающий глобальную иерархию наследования классов в решетку (математическую структуру). NONE не имеет потомков, его нельзя переопределить - это лишь удобная фикция, однако, теоретическое существование такого класса оправдано и служит двум практическим целям:

[x]. Void - пустая ссылка, используемая наряду с другими ссылками, по соглашению имеет тип NONE. (Фактически, Void -это один из компонентов класса GENERAL.)

[x]. Чтобы скрыть компонент от всех клиентов, достаточно экспортировать его только классу NONE. Предложение feature {NONE}(практически эквивалентное feature {}, но записанное явно) или предложение наследования export {NONE}(на практике дающее тот же результат, что и export {}), делает компонент недоступным для любого класса, написанного разработчиком, ибо NONE не имеет потомков. Обратите внимание на то, что NONE скрывает и все свои компоненты.

Первое свойство объясняет, почему значение Void можно присвоить любому элементу ссылочного типа данных. До сих пор статус Void оставался некой загадкой, теперь, когда Void связано с классом NONE, этот статус становится очевидным, официальным и согласующимся с системой типов: по построению NONE является потомком всех классов, а потому мы можем использовать Void как допустимое значение любой ссылки, не нарушая правил описания типов.

По симметрии ко второму свойству заметим, что объявление, начинающееся с feature и экспортирующее все компоненты во все классы, написанные разработчиком, считается сокращением от feature {ANY}. Для повторного экспорта во все классы

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату