Главная страница

дб. Четвертое издание джозеф Джарратано Университет Хьюстон клиэрЛэйк Гари Райли People5oft, Издательский дом "Вильямс" Москва СанктПетербург Киев 2007 ббк 32. 973. 26 018 75 Д


Скачать 3.73 Mb.
НазваниеЧетвертое издание джозеф Джарратано Университет Хьюстон клиэрЛэйк Гари Райли People5oft, Издательский дом "Вильямс" Москва СанктПетербург Киев 2007 ббк 32. 973. 26 018 75 Д
Дата19.05.2022
Размер3.73 Mb.
Формат файлаpdf
Имя файла[Dzharratano Dzhozef, Raili Gar - Nieizviestnyi.pdf
ТипДокументы
#538649
страница66 из 74
1   ...   62   63   64   65   66   67   68   69   ...   74

] [] (* []) *) ся шаблон объекта, то вставляется шаблон initial — object. Если же точке вставки не предшествует ни один шаблон, то для определения типа добавляемого шаблона используется шаблон, который следует заточкой вставки. Для шаблона initial-object применяется следующий формат

11.8. Обработчики сообщений, определяемые пользователем В данном определении терм parameter> — это многозначная переменная, а терм — один из символов around, before, primary или after. По умолчанию любой обработчик сообщений является обработчиком сообщений типа primary. Назначение обработчиков типа around, before и after рассматривается в разделе 11.10. Каждый класс имеет свой собственный набор обработчиков сообщений, поэтому не требуется, чтобы имя — name> отличалось от имен обработчиков сообщений, используемых в других классах. Объявления — parameter> и относятся к параметрам, которые могут передаваться в обработчик сообщений при его вызове. Эти параметры действуют по такому же принципу, как и параметры, применяемые в конструкциях de f f unction. Кроме того, и тело обработчика сообщений,
представленное термом *, ведет себя также, как тело конструкции de f f unction. Для связывания локальных переменных может использоваться функция bind, а возвращаемым значением для обработчика сообщений становится значение последнего выражения, вычисленного в его теле. Рассмотрим следующий примера а) (slot radius)) (defmessage-handler RECTANGLE compute- area () (* (send ?self get-height) (send ?self get-width)))
(defmessage-handler CIRCLE compute-area () (* (pi) (send ?self get-radius) (send ?self get-radius))) (definstances figures (rectangle-
1 of RECTANGLE (height 2) (width 4)) (circle-1 of CIRCLE (radius
3))) В данном примере определяются два класса, RECTANGLE и, с соответствующими слотами. За каждым классом закреплен обработчик сообщений compute-area. Этот обработчик сообщений предназначен для вычисления пло-
Глава 11. Классы, экземпляры и обработчики сообщений Здесь заслуживает внимания то, что каждому экземпляру передается одно и тоже сообщение, но, вычисляя площадь фигуры, заданной сего помощью, каждый экземпляр отвечает по-разному. Такая способность различных экземпляров отвечать на одно и тоже сообщение в характерной для него форме называется полиморфизмом. Сокращенные ссылки на слоты
Если бы всегда приходилось передавать экземпляру сообщения для выборки или установки значения любого слота, то при написании многих программ возникали бы значительные неудобства, поэтому предусмотрен сокращенный механизм,
позволяющий получить доступ к любым слотам экземпляра,
связанного с переменной ? self. Таким образом, вместо применения следующего выражения (send ?self для выборки значения слота можно использовать выражение ?
self: щади каждого объекта. Для класса площадь экземпляра RECTANGLE вычисляется путем умножения высоты, заданной в экземпляре, на ширину. А для класса CIRCLE площадь экземпляра CIRCLE представляет собой значение числа т, возвращаемое функцией pi, которое умножается назначение радиуса, заданное в экземпляре,
возведенное в квадрат. Обратите внимание на то, что в обоих обработчиках сообщений используется переменная ?self. Это специальная переменная, автоматически определяемая для каждого обработчика сообщений. При вызове обработчика сообщений переменной ? self присваивается значение адреса того экземпляра, которому передается сообщение. Эта переменная может применяться для передачи в экземпляр сообщений, как и было сделано в рассматриваемом примере для выборки значений слотов height, width и radius. После определения обработчиков сообщений появляется возможность отправлять сообщения compute — area в экземпляры классов и CIRCLE для получения информации о площади фигуры, заданной этим экземпляром, как в следующем примере (reset)J CLIPS> (send [circle-1] compute-area)J
28.2743338823081 CLIPS> (send [rectangle-1] compute-area)J 8
CLIPS>

11.8. Обработчики сообщений, определяемые пользователем Например, описанные выше обработчики сообщений compute — area можно переопределить следующим образом RECTANGLE compute-area () (* ?self:height ?

self:width)) (defmessage-handler CIRCLE compute-area () (* (pi) ?
self:radius ?self:radius)) Аналогичный механизм может применяться для задания значения слота. Вместо такого выражения (send ?self put- *) может использоваться выражение (bind пате Оба эти альтернативных механизма позволяют обойти этап передачи сообщений и непосредственно манипулировать слотами. Необходимость в этом еще больше возрастает, если на основе обработчиков сообщений get- и put — для создаваемых классов программист определяет обработчики сообщений йоге или around (эта тема рассматривается в разделе По умолчанию в обработчиках сообщений для класса сокращенные ссылки могут применяться только по отношению к слотам, которые непосредственно определены в классе (тек слотам, которые не являются унаследованными. Например,
предположим, что заданы две следующие конструкции de f class:
(defclass A (а USER) (slot x)) (defclass В (а Ау) В таком случае приведенный ниже диалог показывает, что сокращенную ссылку можно использовать лишь для того, чтобы сослаться на слоту, а не на слот х в обработчике сообщений для класса В (defmessage-handler В bmh1 () (* 2 ?self:z))J [NSGFUN6]
Private slot x of class А cannot be accessed directly by handlers attached to class В [PRCCODE3] Undefined variable х referenced in message-handler. ERROR:
886 Глава 11. Классы, экземпляры и обработчики сообщений В bmhl () (* 2 х) ) CLIPS>
(defmessage-handler В bmh2 () (* 2 ?self:y))J CLIPS> В
обработчике сообщений bmh1 создается ссылка на переменную

? sel f: ха это недопустимо, поскольку слот х унаследован от класса А. В обработчике сообщений bmh2 разрешается сделать ссылку на переменную ? self: у, поскольку слоту определен в классе В. В языке COOL поддерживается инкапсуляция объектов, а это означает, что детали реализации класса скрываются от постороннего взгляда и доступ к классу ограничивается вполне определенным интерфейсом обработчиками сообщений, определенными для данного класса.
Поскольку интерфейсом для выборки значений слотах из экземпляров класса A является обработчик сообщений get — х,
то в обработчике сообщений bmh1 и должен использоваться этот интерфейс. С учетом такой поправки обработчик сообщений bmhl может быть безошибочно определен следующим образом CLIPS> (defmessage-handler В bmh1 () (* 2
(send ?self get-x)))J CLIPS> Такой принцип действия слота,
обеспечивающий инкапсуляцию, можно отменить с использованием атрибута слота visibility. Если этому атрибуту присваивается значение private, предусмотренное по умолчанию, то непосредственный доступ к слоту может осуществляться только в обработчиках сообщений класса,
определяющего этот слот. А если данному атрибуту присвоено значение public, ток слоту может быть получен непосредственный доступ в подклассах и суперклассах любого определяющего его класса. В частности, в предыдущем примере применение следующего определения класса А (defclass Ах) позволяет определить обработчик сообщений bmhl таким образом (defmessage-handler В bmh1 () (*
2 х. Обработчики сообщений, определяемые пользователем Отслеживание процесса передачи сообщений и функционирования обработчиков сообщений При отслеживании сообщений или обработчиков сообщений с использование команды watch с параметром messages или message — handlers каждый раз, после того как начинается и заканчивается
выполнение кода обработчика сообщений или начинается и заканчивается передача сообщений, выводится информационное сообщение CLIPS> (watch messages)J CLIPS>
(watch message-handlers)J CLIPS> (send [circle-1] compute-area)J
MSG » compute-area ED:1 () HND » compute- area primary in class CIRCLE ED:1 () HND «
compute-area primary in class CIRCLE ED:1 ()
MSG « compute-area ED:1 () 28.2743338823081
CLIPS> (send [rectangle-1] compute-area)J MSG » compute-area
ED:1 () HND » compute-area primary in class
RECTANGLE ED:1 () HND « compute-area primary in class RECTANGLE ED:1 () MSG «
compute-area ED:1 () 8 CLIPS> Если сообщения отслеживаются с помощью параметра messages, то отладочная информация отображается после передачи в экземпляр сообщения и после полного завершения обработки этого сообщения. Если же с помощью параметра message —
handlers отслеживается функционирование обработчиков сообщений, то отладочная информация выводится после того,
как начинается и заканчивается выполнение кода каждого конкретного обработчика сообщений. При отслеживании функционирования обработчиков сообщений предоставляется вся та информация, которая может быть получена при отслеживании сообщений, а также некоторая дополнительная информация. В приведенном выше диалоге информационные сообщения, выводимые в результате отслеживания сообщений,
обозначались префиксом MSG, а информация, полученная при отслеживании функционирования обработчиков сообщений,
отмечалась префиксом HND. Символ » свидетельствует об инициализации отслеживания определенного со Глава 11. Классы, экземпляры и обработчики сообщений общения или обработчика сообщений, а символ « — о завершении отслеживания конкретного сообщения или обработчика сообщений. За символом » или « следует имя
сообщения или обработчика сообщений. В современной версии языка вслед за именем обработчика сообщений предусматривается вывод некоторой дополнительной информации обозначение типа обработчика сообщений
(Ьейоге, аЙ1ег, primary или around), за которым следует имя класса, связанного сданным конкретным функционирующим обработчиком сообщений. Одно-единственное сообщение способно вызвать на выполнение многочисленные обработчики сообщений различных типов или классов, поэтому данная информация позволяет определить, какой из них фактически функционирует. В последнюю очередь отображается фрагмент информации, показывающий глубину вложенности вызовов,
обозначаемый символом ED, за которым следуют параметры,
передаваемые обработчику сообщений. Как и при использовании конструкций бей, глубина вложенности вызовов позволяет определить, насколько глубоко вложены вызовы конструкций de f function и вызовы обработчиков сообщений. Отсчет глубины вложенности вызовов начинается с нуля, и после каждой передачи управления очередной конструкции de f function или обработчику сообщений глубина увеличивается на единицу. После выхода из каждой конструкции def function или из обработчика сообщений значение глубины вложенности уменьшается на единицу. В списке параметров в первую очередь всегда указывается параметр, представляющий собой значение переменной ? self. После этого перечисляются все явно заданные параметры обработчика сообщений.
Возможно также обеспечить отслеживание функционирования сразу всех обработчиков сообщений конкретного класса, указав имя этого класса для отслеживания функционирования конкретного обработчика сообщений необходимо задать только имя класса и обработчика сообщений для отслеживания функционирования конкретного обработчика сообщений определенного типа необходимо указать класс, имя обработчика сообщений, а после этого тип (Ьейоге, ай

ег, primary или around): CLIPS> (unwatch all)J CLIPS> (watch message-handlers
CIRCLE)J CLIPS> (watch message-handlers RECTANGLE
compute-area)J CLIPS> (watch message-handlers RECTANGLE
get-height primary)J CLIPS> Первая команда watch обеспечивает отслеживание функционирования всех обработчиков сообщений, определяемых пользователем и системой для класса CIRCLE. Вторая команда watch обеспечивает отслеживание функционирования обработчика сообщений compute — area типа primary для класса RECTANGLE
11.8. Обработчики сообщений, определяемые пользователем (и обеспечивала бы отслеживание функционирования обработчиков сообщений типа ай1ег, before и around, если бы они были определены. Третья команда watch отслеживает функционирование только определяемого системой обработчика типа primary для класса RECTANGLE.
КОМИНДЫ бе ййе З ЗаЯе-handler Для манипулирования конструкциями de fmes sage — handler предусмотрено несколько команд. Для отображения текущего списка конструкций de f me s s a— ge — handlers, поддерживаемых системой CLIPS, служит команда list-defmessage-handlers. Эта команда имеет следующий синтаксис (list-defmessage-handlers [ [inherit]]) В данном определении ключевое слово inherit указывает, что в список должны быть включены унаследованные обработчики сообщений. Пример применения команды list — de fmessage-handlers приведен ниже. CLIPS> (list-defmessage- handlers RECTANGLE)J get-height primary in class RECTANGLE
put-height primary in class RECTANGLE get-width primary in class
RECTANGLE put-width primary in class RECTANGLE compute-area primary in class RECTANGLE For а total of 5 message-handlers.
CLIPS> (ppdefmessage-handler
1   ...   62   63   64   65   66   67   68   69   ...   74


написать администратору сайта