Основы объектно-ориентированного программирования
Шрифт:
Цель - сделать Result верным, если и только если значение x находится в массиве a. Использование or здесь будет неверным. В этом случае всегда могут вычисляться два операнда, так что при истинности первого операнда (i > a.upper) произойдет попытка доступа к несуществующему элементу массива a @(aupper+1), что приведет к ошибке во время выполнения (нарушение предусловия при включенной проверке утверждений).
Решение без нестрогих операторов будет неэлегантным.
Другой пример - утверждение, например, инварианта класса, выражающее, что первое значение списка l целых неотрицательно, при условии, что список непустой:
При использовании or инвариант был бы некорректен. Здесь нет способа написать условие без нестрогих операторов (кроме написания специальной функции и вызова ее в утверждении). Базовые библиотеки алгоритмов и структур данных содержат много таких случаев.
Оператор implies, описывающий включения, также нестрогий. Форма implies менее привычна, но часто более ясна, например, последний пример выглядит лучше в записи:
Строки
Класс STRING описывает символьные строки. Он имеет специальный статус, поскольку нотация допускает манифестные строковые константы, обозначающие экземпляры STRING.
Строковая константа записывается в двойных кавычках, например,
Символ двойных кавычек должны предваряться знаком %, если он появляется как один из символов строки.
Неконстантные строки также являются экземплярами класса STRING, чья процедура создания make принимает в качестве аргумента ожидаемую начальную длину строки, так что
динамически размещает строку text1, резервируя пространство для n символов. Заметим, что n– только исходный размер, не максимальный. Любая строка может увеличиваться и сжиматься до произвольного размера.
На экземплярах STRING доступны многочисленные операции: сцепление, выделение символов и подстрок, сравнение и т.д. (Они могут изменять размер строки, автоматически запуская повторное размещение, если размер строки становится больше текущего.)
Присваивание строк означает разделение (sharing): после text2 := text1, любая модификация text1 модифицирует text2, и наоборот. Для получения копии строки, а не копии ссылки, используется клонирование text2 := clone (text1).
Константную строку можно объявить как атрибут:
Ввод и вывод
Два класса библиотеки KERNEL обеспечивают основные средства ввода и вывода: FILE и STD_FILES.
Среди операций, определенных для объекта f типа FILE, есть следующие:
Операции ввода-вывода стандартных файлов ввода, вывода и ошибок, можно наследовать из класса STD_FILES, определяющего компоненты input, output и error. В качестве альтернативы можно использовать предопределенное значение io, как в io.put_string ("ABC"), обходя наследование.
Лексические соглашения
Идентификатор - это последовательность из символа подчеркивания, буквенных и цифровых символов, начинающаяся с буквы. Нет ограничений на длину идентификатора, что позволяет сделать ясными имена компонентов и классов.
Регистр в идентификаторах не учитывается, так что Hi, hi, HI и hI– все означают один и тот же идентификатор. Было бы опасным позволять двум идентификаторам, различающимся только одним символом, скажем Structure и structure, обозначать различные элементы. Лучше попросить разработчиков включить воображение, чем рисковать возникновением ошибок.
Нотация включает набор точных стандартных соглашений по стилю (см. лекцию 26 курса "Основы объектно-ориентированного проектирования"): имена классов (INTEGER, POINT ...) и формальные родовые параметры (G в LIST [G]) записываются в верхнем регистре; предопределенные сущности и выражения (Result, Current...) и константные атрибуты (Pi) начинаются с буквы верхнего регистра и продолжаются в нижнем регистре. Все другие идентификаторы (неконстантные атрибуты, формальные аргументы программ, локальные сущности) - в нижнем регистре. Хотя компиляторы не проверяют эти соглашения, не являющиеся частью спецификации, они важны для удобочитаемости текстов программных продуктов и последовательно применяются в библиотеках и текстах этой книги.
Ключевые концепции
[x]. Внешние программы доступны через хорошо определенный интерфейс.
[x]. Объектная технология может служить в качестве механизма упаковки наследуемого ПО.
[x]. Подпрограммы не могут модифицировать свои аргументы, хотя они могут изменять объекты, связанные с этими аргументами.
[x]. Нотация включает небольшой набор инструкций: присваивания, выбора, цикла, вызова, отладки и проверки.