方案中的方法和属性:方案中是否可以进行OOP? [英] Methods and properties in scheme: is OOP possible in Scheme?

查看:67
本文介绍了方案中的方法和属性:方案中是否可以进行OOP?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将使用一个简单的示例来说明我的问题.在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等花括号语言),则最好仅将参数作为列表(即将参数作为列表) -不需要一个 是列表的参数)并以这种方式处理它们?


更新:

我收到了一些答案,其中包含指向各种扩展程序/库的链接,这些链接可以满足我对计划中OOP的渴望.这很有帮助,谢谢.

尽管我可能没有很好地传达它,但我也想知道什么是最好的方法,而没有这样的类或库来实现上面的pie对象,这样我就可以更好地理解方案的最佳实践. /p>

解决方案

从某种意义上讲,针对Scheme的不同OO系统的堆积帮助 -一个更好的问题可能是使用哪个!

另一方面,如果这是一项教育性练习,则您甚至可以使用闭包对象等效项来滚动自己的内容. (请原谅任何错误,我的计划相当生锈.)

(define (make-pie flavor pieces tastiness)
        (lambda (selector)
                (cond ((eqv? selector 'flavor) flavor)
                      ((eqv? selector 'pieces) pieces)
                      ((eqv? selector 'tastiness) tastiness)
                      ((eqv? selector 'goodness) (* pieces tastiness))
                      (else '()))))

这是pie对象的简单构造函数.参数变量flavorpiecestastiness被lambda表达式封闭,成为对象的字段,而闭包的第一个参数(为简便起见,此处仅此)是方法选择器. /p>

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

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

I will use a simple example to illustrate my question. In Java, C, or any other OOP language, I could create a pie class in a way similar to this:

class Apple{
    public String flavor;
    public int pieces;
    private int tastiness;
    public goodness(){
        return tastiness*pieces;
    }
}

What's the best way to do that with Scheme? I suppose I could do with something like this:

(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

...where cherry is the flavor, 2 is the pieces, and 5 is the tastiness. However then there's no type-safety or visibility, and everything's just shoved in an unlabeled list. How can I improve that?

Sidenote: The make-pie procedure expects 3 arguments. If I want to make some of them optional (like I'd be able to in curly-brace languages like Java or C), is it good practice to just take the arguments in as a list (that is treat the arguments as a list - not require one argument which is a list) and deal with them that way?


Update:

I've received a couple answers with links to various extensions/libraries that can satisfy my hunger for OOP in scheme. That is helpful, so thank you.

However although I may not have communicated it well, I'm also wondering what the best way is to implement the pie object above without such classes or libraries, so I can gain a better understanding of scheme best practices.

解决方案

In some sense, closures and objects are equivalent, so it's certainly possible. There are a heaping helping of different OO systems for Scheme -- a better question might be which one to use!

On the other hand, if this is an educational exercise, you could even roll your own using the closure-object equivalency. (Please forgive any errors, my Scheme is rather rusty.)

(define (make-pie flavor pieces tastiness)
        (lambda (selector)
                (cond ((eqv? selector 'flavor) flavor)
                      ((eqv? selector 'pieces) pieces)
                      ((eqv? selector 'tastiness) tastiness)
                      ((eqv? selector 'goodness) (* pieces tastiness))
                      (else '()))))

This is a simple constructor for a pie object. The parameter variables flavor, pieces and tastiness are closed over by the lambda expression, becoming fields of the object, and the first (and for simplicity's sake here, only) argument to the closure is the method selector.

That done, you can instantiate and poke at some:

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

这篇关于方案中的方法和属性:方案中是否可以进行OOP?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆