首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >R和面向对象编程

R和面向对象编程
EN

Stack Overflow用户
提问于 2012-03-02 02:16:26
回答 3查看 44K关注 0票数 81

在R中,以这样或那样的方式进行面向对象编程是非常有可能的。然而,与Python不同的是,有许多方法可以实现面向对象:

R.oo package

  • S3和classes

  • Reference classes

  • the proto package

  • S4

我的问题是:

在R中,这些面向对象编程方式与的主要区别是什么?

理想情况下,这里的答案将作为R程序员尝试决定哪种OO编程方法最适合他们需求的参考。

因此,我要求提供细节,以客观的方式提出,以经验为基础,并以事实和参考为后盾。澄清这些方法如何映射到标准OO实践的加分。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-02 03:43:56

S3类

  • 并不是真正的对象,而更像是一个围绕的命名convention
  • Based。语法:例如,对于打印,print.default

调用print.lm print.anova,等等。如果找不到,则返回

S4类

复杂

引用类

主要用于避免复制大型对象的

传递

协议

  • ggplot2最初是用proto编写的,但最终将使用S3重写。
  • 的概念很简洁(原型,而不是类),但在it
  • Description of the concept and implementation

版本的ggplot2中似乎很棘手,似乎正在远离proto

R6类

  • By-reference
  • Does not depend classes
  • "Creating S4 R6类与reference类类似,不同之处在于不需要分隔字段和方法,也不能指定字段的类型。“
票数 34
EN

Stack Overflow用户

发布于 2012-03-02 03:56:05

3/8/12编辑:以下答案回应了最初发布的问题中的一部分,该问题后来被删除。我把它复制到下面,为我的答案提供上下文:

如何将不同的OO方法映射到更标准的OO方法?

我的贡献与您的第二个问题有关,即R的OO方法如何映射到更标准的OO方法。正如我过去思考过的那样,我一次又一次地回到了两个段落,一个是Friedrich Leisch的,另一个是John Chambers的。它们都很好地阐明了为什么在R中类似面向对象的编程与在许多其他语言中具有不同的风格。

首先是Friedrich Leisch,摘自"Creating R Packages: A Tutorial“(warning: PDF):

S很少见,因为它既是交互式的,又有面向对象的系统。设计类显然就是编程,但要使S作为交互式数据分析环境有用,它是一种函数式语言是有意义的。在“真正的”面向对象编程(OOP)语言中,如C++或Java类和方法定义紧密地绑定在一起,方法是类(以及对象)的一部分。我们希望为预定义的类添加增量和交互式的方法,比如用户定义的方法。这些添加可以在任何时间点进行,甚至可以在我们分析数据集的同时在命令行提示符下进行。S试图在面向对象和交互式使用之间进行折衷,尽管折衷对于他们试图达到的所有目标来说从来都不是最优的,但它们在实践中往往效果出奇地好。

另一段来自约翰·钱伯斯的杰作“"Software for Data Analysis"”。(Link to quoted passage):

尽管S和其他一些函数式语言支持类和方法,但OOP编程模型与S语言的所有不同之处只有第一点。OOP系统中的方法定义是类的本地定义;不要求一个方法的相同名称对一个不相关的类意味着相同的事情。相反,R中的方法定义并不驻留在类定义中;从概念上讲,它们与泛型函数相关联。类定义直接或通过继承参与确定方法选择。习惯于OOP模型的程序员有时会因为他们的编程没有直接转换到R而感到沮丧或困惑,但它不能。方法的函数使用更复杂,但也更适合具有有意义的函数,不能简化为OOP版本。

票数 19
EN

Stack Overflow用户

发布于 2012-03-02 06:55:45

S3和S4似乎是OO编程的官方(即内置)方法。我已经开始结合使用S3和嵌入在构造函数/方法中的函数了。我的目标是拥有一个对象$method()类型的语法,这样我就有了半私有字段。我之所以说半私密,是因为(据我所知)没有办法真正隐藏它们。下面是一个简单的例子,它实际上并没有做任何事情:

代码语言:javascript
运行
复制
#' Constructor
EmailClass <- function(name, email) {
    nc = list(
        name = name,
        email = email,
        get = function(x) nc[[x]],
        set = function(x, value) nc[[x]] <<- value,
        props = list(),
        history = list(),
        getHistory = function() return(nc$history),
        getNumMessagesSent = function() return(length(nc$history))
    )
    #Add a few more methods
    nc$sendMail = function(to) {
        cat(paste("Sending mail to", to, 'from', nc$email))
        h <- nc$history
        h[[(length(h)+1)]] <- list(to=to, timestamp=Sys.time())
        assign('history', h, envir=nc)
    }
    nc$addProp = function(name, value) {
        p <- nc$props
        p[[name]] <- value
        assign('props', p, envir=nc)
    }
    nc <- list2env(nc)
    class(nc) <- "EmailClass"
    return(nc)
}

#' Define S3 generic method for the print function.
print.EmailClass <- function(x) {
    if(class(x) != "EmailClass") stop();
    cat(paste(x$get("name"), "'s email address is ", x$get("email"), sep=''))
}

和一些测试代码:

代码语言:javascript
运行
复制
    test <- EmailClass(name="Jason", "jason@bryer.org")
    test$addProp('hello', 'world')
    test$props
    test
    class(test)
    str(test)
    test$get("name")
    test$get("email")
    test$set("name", "Heather")
    test$get("name")
    test
    test$sendMail("jbryer@excelsior.edu")
    test$getHistory()
    test$sendMail("test@domain.edu")
    test$getNumMessagesSent()

    test2 <- EmailClass("Nobody", "dontemailme@nowhere.com")
    test2
    test2$props
    test2$getHistory()
    test2$sendMail('nobody@exclesior.edu')

这是我写的一篇关于这种方法的博客文章的链接:http://bryer.org/2012/object-oriented-programming-in-r我欢迎对这种方法的评论、批评和建议,因为我不相信这是最好的方法。然而,对于我试图解决的问题,它工作得很好。具体地说,对于XML包(http://jbryer.github.com/makeR),我不希望用户直接更改数据字段,因为我需要确保表示对象状态的makeR文件保持同步。只要用户遵守我在文档中概述的规则,这就可以完美地工作。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9521651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档