(defmessage-handler A set-foo (?value)
(bind?self:foo?value))
При определении обработчиков прямой доступ к слоту статически связывается с соответствующим слотом. Поэтому особого внимания требуют ситуации, при которых прямой доступ к слоту выполняется с помощью посылки сообщения объекту, являющемуся экземпляром подкласса класса, с которым было связано данное сообщение. Если данный подкласс переопределяет слот, к которому осуществляет прямой доступ обработчик сообщения суперкласса, CLIPS остановит выполнение и выведет сообщение об ошибке. Ошибка в данном случае происходит из-за того, что обработчик сообщения суперкласса статически связан со слотом суперкласса, который переопределил предок. Для демонстрации возникновения данной ошибки приведем пример 11.36.
Пример 11.36. Переопределение слотов
(defclass A (is-a USER)
(slot foo (create-accessor read)))
(defclass В (is-a A)
(role concrete)
(slot foo (create-accessor write)))
В данном примере класс а определяет слот foo и стандартный акцессор для чтения значения этого слота. Класс B является потомком класса а, переопределяет слот foo и не переопределяет акцессор чтения. Поэтому посылка объекту класса B сообщения get-foo приведет к возникновению ошибки. Данная ситуация продемонстрирована на рис. 11.14.
|
|
Для решения подобной проблемы необходимо предпринять следующие шаги. Во-первых, переопределенные в классе наследнике слоты нужно определить с гранью visibility public. Во-вторых, обработчики, осуществляющие доступ к слотам, которые могут быть переопределены, должны использовать функции dynamic-put и dynamic-get. Приведенный выше пример можно переписать следующим образом: