end

В этом случае любой вызов x.i(...) недопустим. Единственная возможность обращения к i - неквалифицированный вызов

i (...)

в тексте подпрограммы класса S3 или его потомков. Такой механизм обеспечивает полное скрытие информации.

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

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

Стиль объявления скрытых компонент

Использованный выше стиль объявления скрытой компоненты i не слишком удачен. Это хорошо видно в следующем примере (Не рекомендуемый стиль (см. ниже S5).)

class S4 feature

exported ...

feature {}

secret ...

end

где secret является скрытой компонентой, а exported - общедоступной. Разница в написании feature {} с пустым списком в скобках и feature без всяких скобок едва заметна. Гораздо разумнее вместо пустого использовать список, содержащий единственный класс NONE (Рекомендуемый стиль.)

class S5 feature

... exported ...

feature {NONE}

... secret ...

end

Класс NONE является базовым библиотечным классом и обсуждается далее в связи с наследованием. По определению он не может иметь потомков и нельзя создать его экземпляр. Таким образом, компонент, экспортированный классу NONE, фактически является скрытым. Между объявлениями S4 и S5 нет принципиальной разницы, однако во втором случае исходный текст становится более понятным и удобочитаемым. Именно такой стиль объявления скрытых компонент будет использоваться далее в этой книге.

'Внутренний' экспорт

Рассмотрим объявление класса

indexing

замечание: 'Ошибочное объявление (объяснение см. ниже)'

class S6 feature

x: S6

my_routine is do ... print (x.secret) ... end

feature {NONE}

secret: INTEGER

end -- class S6

Наличие в объявлении класса атрибута x типа S6 и вызова x.secret делает его собственным клиентом. Но такой вызов недопустим, так как компонент secret скрыт от всех клиентов! Тот факт, что неавторизованным клиентом является сам класс S6, нечего не меняет - объявленный статус secret делает недопустимым любой вызов вида x.secret. Всякие исключения нарушают простоту сформулированного правила.

Есть простое решение: написать вместо feature {NONE} предложение feature {S6} , экспортируя компоненту самому себе и своим потомкам.

Необходимо отметить, что подобный прием необходим, только если в тексте класса присутствует квалифицированный вызов аналогичный print (x.secret). Очевидно, что неквалифицированный вызов secret в инструкции print (secret) допустим без дополнительных ухищрений. Все компоненты, объявленные в данном классе, могут использоваться в подпрограммах данного класса и его потомков. Только при наличии квалифицированных вызовов приходится экспортировать компонент самому себе.

Собираем все вместе

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

Общая относительность

Удивительно, но все приведенные до сих пор описания того, что происходит во время выполнения, были относительными. Результат выполнения подпрограммы всегда связан с текущим экземпляром, который в исходном тексте класса неизвестен. Можно попытаться понять действие вызова, только принимая во внимание цель этого вызова, например p1 в следующем примере:

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

0

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

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