Scheme中的继承类

时间:2010-03-04 19:23:10

标签: inheritance lisp scheme

现在我研究一下Scheme的OOP部分。我可以在Scheme中定义类:

(define (create-queue)
  (let ((mpty #t) 
        (the-list '()))

    (define (enque value)
      (set! the-list (append the-list (list value)))
      (set! mpty #f)
      the-list)

    (define (deque)
      (set! the-list (cdr the-list))
      (if (= (length the-list) 0) 
      (set! mpty #t))
      the-list)

    (define (isEmpty)
      mpty)

    (define (ptl)
      the-list)

    (define (dispatch method)
      (cond ((eq? method 'enque) enque)
        ((eq? method 'deque) deque)
        ((eq? method 'isEmpty) isEmpty)
        ((eq? method 'print) ptl)))

    dispatch))

(来自css.freetonik.com的例子)

我可以在Scheme中实现类继承吗?

4 个答案:

答案 0 :(得分:6)

好吧,我不会称那是一堂课,但那只是我。这只是封闭和原始计划。

Scheme本身没有对象系统。但是,Scheme能够实现类系统。

如果您想使用oop系统,可以尝试使用Scheme编写的几个。

Here是一个列出几个的链接,肯定还有其他链接。

答案 1 :(得分:3)

如果您确定要推出自己的OOP系统,那么您当然可以在Scheme中实现继承。这样做的一种方法是关闭所需的超类的实例,当你创建派生类的实例时,它是“构造的”,并且在dispatch过程中有一个额外的子句,比如

(define (make-superclass-instance) 
  (define (method-a)
    (display "a!"))

  (define (method-b)
    (display "b!"))

  (define (dispatch message)
    (case message
      ((a) (method-a))
      ((b) (method-b))
      (else (error "nonexistent method"))))

  dispatch)

  (define (make-class-instance)
    (let ((super (make-superclass-instance)))
      (define (method-c)
        (display "c!"))

      (define (method-a)
        (display "overridden a!"))

      (define (dispatch message)
        (case message
          ((c) (method-c))
          ((a) (method-a))
          (else (super message))))

      dispatch))

这也允许轻松覆盖方法,如示例中所示。

当然,这非常繁琐,并且涉及大量的样板。你可以用宏来使它变得更加愉快,但是如果你对在Scheme中实际进行OOP而不是作为学习练习进行实验感兴趣,那么Will Hartung的suggestion将使用Scheme中许多现有的对象系统之一。

答案 2 :(得分:2)

OOP语言使用继承来模拟多态,即创建一类可以响应已发布消息列表的对象。您可以在Scheme中使用多态,而无需显式继承,因为它是动态类型语言。比较Java中“Animal”类的实现及其在Scheme中的相应实现:

// Animal interface and implementations in Java

interface Animal {
    void cry (); // The only message to which an Animal object will respond.
}

class Cat implements Animal {
    void cry () {
        System.out.println ("meow!");
    }
}

class Cow implements Animal {
    void cry () {
        System.out.println ("baee!");
    }
}

// Usage

Animal a = new Cat ();
Animal b = new Cow ();
a.cry (); => "meow!"
b.cry (); => "baee!"

现在使用闭包在Scheme中相应的实现:

;; A factory of Animals.
(define (animal type)
  (case type
    ((cat) (cat))
    ((cow) (cow))))

;; Corresponds to class Cat in Java.
(define (cat)
  (lambda (msg)
    (case msg
      ((cry) "meow!"))))

;; Corresponds to class Cow in Java.
(define (cow)
  (lambda (msg)
    (case msg
      ((cry) "baee!"))))

;; Sample usage

(define a (animal 'cat))
(define b (animal 'cow))
(a 'cry) => "meow!"
(b 'cry) => "baee!"

事实上,只有当我们必须处理过多的私人状态时,我们才需要关闭。 Scheme提供了许多方法来模拟如上所述的简单“类层次结构”。这是我们开发一个小的“消息调度”工具的一种方法,我们可以在对象列表中使用它:

;; Generic message dispatch.
(define (send type message objects)
    ((cdr (assq message (cdr (assq type objects))))))

;; A list of animals.
(define animals (list (cons 'cat (list (cons 'cry (lambda () "meow!"))))
                   (cons 'cow (list (cons 'cry (lambda () "blaee!"))))))

;; Send a specific message to a specific animal:
(send 'cat 'cry animals) => "meow!"
(send 'cow 'cry animals) => "blaee!"

Scheme提供的功能抽象机制足以让我们不用担心完整的对象系统。还有一些Scheme的对象系统。请查看Tiny-CLOS(基于CLOS)。本书Lisp in Small Pieces讨论了对象系统的实现(基于Meroon)。

答案 3 :(得分:0)

PLT计划中有一个非常完善的课程系统:

http://docs.plt-scheme.org/guide/classes.html