Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
scheme中的方法和属性:scheme中是否可以实现OOP?_Oop_Scheme_Racket - Fatal编程技术网

scheme中的方法和属性:scheme中是否可以实现OOP?

scheme中的方法和属性:scheme中是否可以实现OOP?,oop,scheme,racket,Oop,Scheme,Racket,我将用一个简单的例子来说明我的问题。在Java、C或任何其他OOP语言中,我可以用类似以下方式创建pie类: class Apple{ public String flavor; public int pieces; private int tastiness; public goodness(){ return tastiness*pieces; } } 使用Scheme实现这一点的最佳方法是什么?我想我可以这样做: (define m

我将用一个简单的例子来说明我的问题。在Java、C或任何其他OOP语言中,我可以用类似以下方式创建
pie
类:

class Apple{
    public String flavor;
    public int pieces;
    private int tastiness;
    public goodness(){
        return tastiness*pieces;
    }
}
使用Scheme实现这一点的最佳方法是什么?我想我可以这样做:

(define make-pie
  (lambda (flavor pieces tastiness)
    (list flavor pieces tastiness)))

(define pie-goodness
  (lambda (pie)
    (* (list-ref pie 1) (list-ref pie 2))))

(pie-goodness (make-pie 'cherry 2 5))

;output: 10
…其中樱桃是味道,2是碎片,5是味道。然而,没有类型安全性或可见性,所有内容都被推到了一个未标记的列表中。我该如何改进呢

旁注:make pie过程需要3个参数。如果我想让其中一些参数成为可选的(比如我可以在Java或C等大括号语言中使用),那么将这些参数作为列表(也就是说,将这些参数视为列表,而不需要一个列表参数)并以这种方式处理它们,这是一种好的做法吗


更新: 我收到了一些答案,其中有指向各种扩展/库的链接,可以满足我对scheme中OOP的渴望。这很有帮助,所以谢谢你

然而,尽管我可能没有很好地传达它,但我也在想,在没有此类类或库的情况下实现上面的
pie
对象的最佳方法是什么,这样我就可以更好地理解scheme最佳实践。

在某种意义上,这当然是可能的。还有一个更好的问题,那就是使用哪一个

另一方面,如果这是一个教育性练习,您甚至可以使用闭包对象等价性来滚动自己的。(请原谅我的错误,我的计划已经过时了。)

这是一个用于
pie
对象的简单构造函数。参数变量
flavor
parties
tastuty
被lambda表达式关闭,成为对象的字段,并且闭包的第一个(为了简单起见,这里仅此)参数是方法选择器

完成后,您可以实例化和戳一些:

> (define pie1 (make-pie "rhubarb" 8 4))
> (define pie2 (make-pie "pumpkin" 6 7))
> (pie1 'flavor)
"rhubarb"
> (pie1 'goodness)
32
> (pie2 'flavor)
"pumpkin"

许多方案允许您定义包含字段和方法的类。例如,请参见:


我建议这样做:

(define PersonClass (lambda (name age strength life)
    (let ((name name)(age age) (life life) (strength strength))
        (lambda (command data)
        (cond
            ((< life 1)
            "I am dead")
            ((equal? command "name")
            name)
            ((equal? command "age")
            age)
            ((equal? command "birthday")
            (set! age(+ age 1)))
            ((equal? command "receive damage")
            (begin (set! life(- life Data)) (display "I received damage\n")))
            ((equal? command "hit")
            (data "receive damage" strength))
            )))))
(定义PersonClass(lambda)(名称年龄强度寿命)
(让((姓名)(年龄)(寿命)(力量))
(lambda(命令数据)
(续)
(

像这样使用:
(Karl“name”0)

大多数方案支持SRFI-9记录或类似的R7RS记录,而R6RS也提供语法稍有不同的记录。这些记录是在scheme中创建新类型的一种方法。此外,大多数方案以及R6R和R7R都支持模块或库,这是封装此类类型操作的一种方法

根据应用程序的性质,许多scheme程序员使用它们而不是OOP来编写程序。记录提供类型及其字段;提供了一个相关程序,用于创建此类型的新对象;将记录作为参数(通常为第一个参数)的其他过程提供对类型的所需操作;模块/库定义确定哪些导出为用户代码,哪些是模块/库实现的专用代码


如果记录字段本身是一个过程,它也可以将私有数据作为闭包:但通常您希望使用模块定义进行数据隐藏和封装,而不是闭包(通常效率更高)。

谢谢。我已经更新了我的问题,以进一步说明我在寻找什么。这些链接(特别是第二个)看起来很有趣,但我也在想,如果没有这些东西,
pie
将如何实现——我对scheme还不熟悉,希望尽早了解一些最佳实践。例如,我是否可以将这些值保存在这样的列表中?啊!面向C#/Java的语法突出显示对Scheme代码进行了大量的哈希处理。我在这里列出了一个简单方法的例子,可以自己做;您应该使用哪个OO系统主要取决于您的需求,或者更可能取决于您所选择的方案实现的可用内容。@Jerfrey's edit:Nice!使用该技术(尤其是方法)是否被视为良好实践?是的,语法突出显示对于scheme来说是非常残酷的-使用
quote
而不是
,可能会有帮助,但我认为这有点冗长。你的愿望是我的命令。请看我的例子。;-)
(define PersonClass (lambda (name age strength life)
    (let ((name name)(age age) (life life) (strength strength))
        (lambda (command data)
        (cond
            ((< life 1)
            "I am dead")
            ((equal? command "name")
            name)
            ((equal? command "age")
            age)
            ((equal? command "birthday")
            (set! age(+ age 1)))
            ((equal? command "receive damage")
            (begin (set! life(- life Data)) (display "I received damage\n")))
            ((equal? command "hit")
            (data "receive damage" strength))
            )))))