Переопределить :INITFORM слота класса в подклассе

Мне нужно немного обобщить значение слота по умолчанию в подклассе.

Пример:

(defclass class-a ()
  ((slot-1 :initarg :slot-1 :initform #'identity)
   <...> other-slots<...>))

Его подкласс

(defclass class-b (class-a)
  ((slot-2 :initarg :slot-2 :initform 0)))

Но #'IDENTITY недостаточно хорош как значение по умолчанию, немного более общее

(lambda (&rest x) x)

подойдет лучше, так как ожидает несколько аргументов (я думаю, что это не противоречит принципу Лискова). Каков наилучший способ переопределить :INITFORM для CLASS-B?

  1. Я могу добавить INITIALIZE-INSTANCE :AFTER для CLASS-B и посмотреть, установлено ли SLOT-1 значение #'IDENTITY, и переопределить его.
  2. Что произойдет, если я снова введу SLOT-1 в CLASS-B? Я бы хотел избежать этого, так как мне пришлось бы повторять для него всю информацию о слоте.

person mobiuseng    schedule 28.07.2016    source источник
comment
Вы должны иметь возможность просто добавить SLOT1 только с новым :INITFORM в подклассе (больше ничего повторять не нужно). Согласно спецификации, используется наиболее конкретная форма инициализации.   -  person jkiiski    schedule 28.07.2016
comment
См. также default-initargs   -  person coredump    schedule 28.07.2016


Ответы (2)


Что произойдет, если я повторно введу SLOT-1 в CLASS-B?

Оно работает.

Я бы хотел избежать этого, так как мне пришлось бы повторять для него всю информацию о слоте.

Нет. Только разница.

person Rainer Joswig    schedule 28.07.2016

Простой альтернативой является использование :default-initargs для класса вместо :initform для слота. В этом случае вам просто нужно предоставить новый default-initarg для этого слота в подклассе. См. обоснование Криса Рисбека для :default-initargs и см. примеры в этом lisptip.

person Xach    schedule 28.07.2016
comment
Хорошо знать! :IDEFAULT-INITARGS раньше не видел. Спасибо - person mobiuseng; 29.07.2016