Мультидиспетчеризация не по типам - Lisp

Узнай цену своей работы

Формулировка задачи:

что то я везде встречаю примеры мультидиспетчеризаци по типам. А как в лиспе диспетчеризовать не по типам, а по друзим вещам, по слотам, например? Как будет выглядеть на лисповских мультиметодах аналог вот такого вот кода?
Листинг программы
  1. A := Object clone do(
  2. a := 0
  3. accept := method(visitor, visitor doA(self))
  4. )
  5. B := Object clone do(
  6. b := 0
  7. accept := method(visitor, visitor doB(self))
  8. )
  9.  
  10. Visitor := Object clone do(
  11. doA := method(acceptor, acceptor a = acceptor a + 1)
  12. doB := method(acceptor, acceptor b = acceptor b + 1)
  13. )
  14.  
  15. a := A clone
  16. b := B clone
  17. visitor := Visitor clone
  18.  
  19. list(a, b) foreach(acceptor, acceptor accept(visitor))
  20.  
  21. writeln(a a, b b) #>>>>11

Решение задачи: «Мультидиспетчеризация не по типам»

textual
Листинг программы
  1. (defclass a-class ()
  2.   ((a :initform 0 :accessor a)))
  3.  
  4. (defclass b-class ()
  5.   ((b :initform 0 :accessor b)))
  6.  
  7. (defun do-a (obj)
  8.   (incf (a obj)))
  9.  
  10. (defun do-b (obj)
  11.   (incf (slot-value obj 'b)))
  12.  
  13. (defclass visitor () ())
  14.  
  15. (defgeneric accept (who whom))
  16.  
  17. (defmethod accept ((who a-class) (whom visitor))
  18.   (declare (ignore whom))
  19.   (do-a who))
  20.  
  21. (defmethod accept ((who b-class) (whom visitor))
  22.   (declare (ignore whom))
  23.   (do-b who))
  24.  
  25. (let ((a-guy (make-instance 'a-class))
  26.       (b-guy (make-instance 'b-class))
  27.       (visitor (make-instance 'visitor)))
  28.   (dolist (acceptor (list a-guy b-guy))
  29.     (accept acceptor visitor))
  30.   (format t "~^~S ~S~%" (a a-guy) (b b-guy)))
  31. ; 1 1

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

В коде определены два класса: a-class и b-class. У каждого из них есть свой атрибут: a и b соответственно. Также определены два метода: do-a и do-b, которые увеличивают значение соответствующего атрибута на единицу. Следующий класс — visitor — представляет собой посетитель, который используется для навещания объектов и увеличения их атрибутов. Определённый затем метод accept является общим для двух классов и увеличивает значение атрибута a или b в зависимости от того, какой класс навещает посетитель. Далее создаются два объекта: a-guy и b-guy, которые представляют собой экземпляры классов a-class и b-class соответственно. Затем создаётся объект visitor, который является экземпляром класса visitor. В цикле dolist перебираются два элемента — a-guy и b-guy. Для каждого из них вызывается метод accept, который увеличивает значение соответствующего атрибута на единицу. В конце выводится сообщение с значениями атрибутов a и b созданных объектов.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 3.786 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы