Чтение онлайн

ЖАНРЫ

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

Мейер Бертран

Шрифт:

[x]. Читабельность: читающему текст легче понять смысл US_states_count, чем числа 50;

[x]. Расширяемость: символическую константу легко обновить, исправив лишь ее определение.

Принцип допускает применение манифестных или, как часто говорят, неименованных констант в качестве "начальных" элементов разнообразных операций, как в случае с циклом from i = 1 until i > n (Но n, конечно, должно быть символической константой).

Итак, нам нужен простой и ясный способ определения символических констант.

Атрибуты-константы

Как и все сущности, символические константы должны быть определены внутри класса. Будем рассматривать константы как атрибуты с фиксированным значением, одинаковым для всех экземпляров класса.

Синтаксически вновь используем служебное слово is, применяемое при описании методов, только здесь за ним будет следовать не алгоритм, а значение нужного типа. Вот примеры определения констант базовых типов INTEGER, BOOLEAN, REAL и CHARACTER:

Zero: INTEGER is 0

Ok: BOOLEAN is True

Pi: REAL is 3.1415926524

Backslash: CHARACTER is '\'

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

Потомки не могут переопределять значения атрибутов-констант.

Как и другие атрибуты, класс может экспортировать константы или скрывать. Так, если C– класс, экспортирующий выше объявленные константы, а у клиента класса к сущности x присоединен объект типа C, то выражение x.Backslash обозначает символ '\'.

В отличие от атрибутов-переменных, константы не занимают в памяти места. Их введение не связано с издержками в период выполнения, а потому не страшно, если их в классе достаточно много.

Использование констант

Вот пример, показывающий, как клиент может применять константы, определенные в классе:

class FILE feature

error_code: INTEGER; -- Атрибут-переменная

Ok: INTEGER is 0

Open_error: INTEGER is 1

...

open (file_name: STRING) is

– - Открыть файл с именем file_name

– - и связать его с текущим файловым объектом

do

error_code := Ok

...

if "Что-то не так" then

error_code := Open_error

end

end

... Прочие компоненты ...

end

Клиент может вызвать метод open и проверить успешность операции:

f: FILE; ...

f.open

if f.error_code = f.Open_error then

"Принять меры"

else

...

end

Нередко нужны и наборы констант, не связанных с конкретным объектом. Их, как и раньше, можно объединить в класс, выступающий в роли родителя всех классов, которым необходимы константы. В этом случае можно не создавать экземпляр класса:

class EDITOR_CONSTANTS

feature

Insert: CHARACTER is 'i'

Delete: CHARACTER is 'd'; -- и т.д.

...

end

class SOME_CLASS_FOR_THE_EDITOR

inherit

EDITOR_CONSTANTS

...Другие возможные родители ...

feature ...

... подпрограммы класса имеют доступ к константам, описанным в EDITOR_CONSTANTS ...

end

Класс, подобный EDITOR_CONSTANTS, служит лишь для размещения в нем группы констант, и его роль как "реализации АТД" (а это - наше рабочее определение класса) не столь очевидна, как в предыдущих примерах. Теоретическое обоснование введения таких классов мы обсудим позднее. Представленная схема работоспособна только при множественном наследовании, поскольку классу SOME_CLASS_FOR_THE_EDITOR могут потребоваться и другие родители.

Константы пользовательских классов

Символические константы полезны не только при работе с предопределенными типами, такими как INTEGER. Они нужны и тогда, когда их значениями являются объекты классов, созданных разработчиком. В этом случае решение не столь очевидно.

Константы с манифестом для этого непригодны

Первым примером служит класс, описывающий комплексное число:

class COMPLEX creation

make_cartesian, make_polar

feature

x, y: REAL

– - Действительная и мнимая часть

make_cartesian (a, b: REAL) is

– - Установить действительную часть a, мнимую - b.

do

x := a; y := b

end

... Прочие методы (помимо x и y, других атрибутов нет) ...

end

Пусть мы хотим определить константу - комплексное число i, действительная часть которого равна 0, а мнимая 1. Первое, что приходит в голову, - это буквальная константа вида

i: COMPLEX is "Выражение, определяющее комплексное число (0, 1)"

Как записать выражение после is? Для пользовательских типов данных никакой формы записи неименованных констант не существует.

Можно представить себе вариант нотации на основе атрибутов класса:

i: COMPLEX is COMPLEX (0, 1)

Но этот подход, хотя и реализован в некоторых ОО-языках, противоречит принципу модульности - основе объектной методологии. Приняв этот подход, мы согласились бы с тем, что клиенты COMPLEX должны описывать константы в терминах реализации класса, а это нарушает принцип Скрытия информации.

Поделиться с друзьями: