现在我研究OOP——Scheme的一部分。我可以像这样在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中实现类继承吗?
嗯,我不会称其为类,但这就是我。这只是闭包和原始方案。
Scheme本身没有对象系统。然而,Scheme 能够实现等级系统。
如果你想使用 oop 系统,有几个为Scheme编写的系统你可以尝试。
这里是一个列出了几个的链接,当然还有其他。
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一书讨论了Scheme对象系统的实现(基于Meroon)。
如果您决定确实想要推出自己的 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的建议,使用Scheme的许多现有对象系统之一。
PLT计划中有一个相当完善的班级系统: