2016-07-28 2 views
1

Мне нужно немного обобщить значение слота по умолчанию в подклассе.Override: 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? Я бы хотел избежать этого, так как мне пришлось бы повторить всю информацию о слотах.
+4

Вы должны просто добавить 'SLOT1' только с новым': INITFORM' в подкласс (не нужно ничего повторять). Согласно [spec] (http://www.lispworks.com/documentation/HyperSpec/Body/07_ec.htm) используется наиболее конкретная initform. – jkiiski

+3

См. Также default-initargs – coredump

ответ

6

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

Это работает.

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

No. Только разница.

4

Для простой альтернативы использовать :default-initargs для класса вместо :initform для слота. В этом случае вам просто нужно предоставить новый по умолчанию-initarg для этого слота в подклассе. См. Chris Riesbeck's rationale для :default-initargs и для примера см. this lisptip.

+0

Полезно знать! Не видели ': IDEFAULT-INITARGS' раньше. благодаря – mobiuseng

Смежные вопросы