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

         

Перекрытие инициализации по умолчанию


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

indexing ... class C creation p1, p2, ... feature ... Объявления компонент, включая реализацию процедур p1, p2, ... end

Совет, отражающий стиль: в случае класса с единственной процедурой создания - для нее рекомендуется имя make. Для классов с двумя и более процедурами создания желателен префикс make_, за которым следует квалификатор, как в следующем примере POINT. (См. "Правильный выбор имен", лекция 8 курса "Основы объектно-ориентированного проектирования")

Соответствующая инструкция создания в этих случаях имеет другую форму:

create x.p (...)

где p одна из процедур создания перечисленных в разделе creation, и в круглых скобках (...) перечисляются фактические аргументы p. Результатом является создание объекта с использованием значений по умолчанию, как и ранее, а затем вызов p с заданными аргументами. Такая инструкция является комбинацией инструкции создания и вызова процедуры и называется порождающим вызовом (creation call). (Оригинальная версия класса POINT приведена в лекции 7)

В качестве примера добавим две процедуры создания в класс POINT, что позволит клиентам при создании новой точки указывать ее начальные координаты - декартовы или полярные. Введем процедуры создания: make_cartesian и make_polar. Вот схема:

class POINT1 creation make_cartesian, make_polar feature ... Компоненты из предыдущей версии класса: x, y, ro, theta, translate, scale, ... feature {NONE} - Этот вариант экспорта рассмотрен ниже. make_cartesian (a, b: REAL) is -- Инициализация точки с декартовыми координатами a и b. do x := a; y := b end make_ polar (r, t: REAL) is -- Инициализация точки с полярными координатами r и t. do x := r * cos (t); y := r * sin (t) end end


Для такого класса клиент будет создавать точки инструкциями вида:

create my_point.make_cartesian (0, 1) create my_point.make_polar (1, Pi/2)

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

Эффект порождающего вызова

Рассмотрим порождающий вызов в форме create x.p(...).

Пусть тип цели x это ссылочный тип, основанный на классе C, p(...) - процедура создания класса C, с заданным списком фактических аргументов. Эффект вызова состоит в выполнении следующих четырех шагов:

  • (C1) Создание нового экземпляра C (набора полей, по одному на каждый атрибут C). Пусть OC - это новый экземпляр.
  • (C2) Инициализация каждого поля OC соответствующими стандартными значениями по умолчанию.
  • (C3) Присоединение значения x (ссылки) к OC.
  • (С4) Вызов процедуры p c заданными аргументами и с целевым объектом OC.



Содержание раздела