2010-03-04 31 views
1

現在我研究計劃的OOP部分。我可以在流程定義類這樣的:計劃中的遺傳類

(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例)

能否實現方案類繼承?

回答

6

嗯,我不會說那個班,但那只是我。這只是關閉和原始計劃。

方案本身沒有對象系統。但是,Scheme可以實現一個班級系統。

如果你想使用一個oop系統,有幾個你可以嘗試的方案。

Here是一個鏈接,列出了幾個,肯定有其他。

+0

+1我不認爲這是一類,無論是。 – anthares 2010-03-05 13:10:50

+0

這些「OOP」系統使用閉包,原始Scheme和宏來實現可讀性。 CLOS也是這樣實施的。正因爲如此,他們同樣不屬於「一類」。 這就是Lisp家族的美麗。 當然,你總是可以爭辯說他的實現是不完整的,而且他缺少<在這裏插入你最喜歡的面向對象功能>。 – 2010-05-23 13:39:13

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

OOP語言使用繼承來模擬多態,即創建一個對象類,它可以響應已發佈的消息列表。您可以在Scheme中使用多態,而無需顯式繼承,因爲它是一種動態類型的語言。比較Java中的「動物」類的方案執行情況和它的實現:

// 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!" 

現在計劃使用閉相應的實施:

;; 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還有一些對象系統。看看Tiny-CLOS(根據CLOS)。本書Lisp in Small Pieces討論了一個Scheme對象系統的實現(基於Meroon)。