2012-03-01 75 views
71

面向对象程序设计是R.很可能然而,不同于例如Python中,有很多方法可以实现面向对象:R和面向对象在这种或那种方式编程

我的问题是:

什么主要差异区分这些方式的R在OO编程?

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

因此,我要求的是细节,以客观的方式,根据经验提出,并以事实和参考为后盾。说明的奖励积分如何这些方法映射到标准的OO实践。

+1

参考资料上的信息:http://stackoverflow.com/questions/5137199/what-is-the-significance-of-the-new-reference-classes – 2012-03-01 18:29:07

+0

谢谢,你能重新发布链接作为答案吗?如果你可以包含什么参考类的小概要,以及为什么他们更喜欢S3/S4类,那将会很好。 – 2012-03-01 18:34:19

+0

一只小鸟在我耳边低声说约翰钱伯斯即将出版一本书。但不要告诉任何人我说过的话; ;-) – 2012-03-01 18:41:53

回答

32

S3类

  • 不是真的对象,更多的命名约定
  • 周围为主。语法:例如打印,print调用print.lmprint.anova等,如果没有找到,print.default

S4类

参考类

R6类

  • By-reference
  • 不依赖于S4类
  • Creating R6类与引用类相似,不同之处在于不需要分隔字段和方法,也不能指定字段的类型。”在12年3月8日
+1

如果你有其他的不同点,可以随意编辑。如果它变成CW,我不会哭的:-) – 2012-03-01 19:45:58

+3

别忘了'library(“fortunes”);财富(“海峡”)' – 2012-03-01 21:01:29

+1

关于S4类的讨论在这里:http://stackoverflow.com/questions/3602154/when-does-it-pay-off-to-use-s4-methods-in-r-programming 。总的感觉似乎是,他们在获得优势时更麻烦。 – 2012-03-01 22:48:17

19

编辑:答案下面响应一块它现在已经被删除了最初发布问题。我已将其复制到下面,为我的答案提供上下文:

不同的OO方法如何映射到例如在标准方法中使用的更标准的OO方法。 Java还是Python?


我的贡献涉及到第二个问题,关于R的OO方法是如何映射到更标准的OO方法。正如我以前想过的那样,我一次又一次地回到了两段,一段是弗里德里希莱施,另一段是约翰钱伯斯。他们都很好地阐述了为什么R中类OO编程与其他许多语言相比具有不同的风格。

首先,弗里德里希Leisch,从“创建R程序包:教程”(warning: PDF):

S是罕见的,因为它是交互和对面向对象的系统。显然,设计类是编程,但要使S成为交互式数据分析环境很有用,它是一种功能语言是合理的。在“真正的”面向对象编程(OOP)语言(如C++或Java类)和方法定义紧密绑定在一起时,方法是类(以及对象)的一部分。我们希望像预定义类的用户定义方法那样增加和交互式添加。这些添加可以在任何时间点进行,即使在我们分析数据集时,也可以在命令行提示符下进行。 S试图在面向对象和交互使用之间做出妥协,虽然折衷在所有他们试图达到的目标上都不是最优的,但它们在实践中往往工作得非常出色。

另一段来自约翰钱伯斯的精湛书籍"Software for Data Analysis"。 (Link to quoted passage):

的OOP编程模型在所有S语言,但第一 点不同,即使S和一些其他功能的语言支持类 和方法。 OOP系统中的方法定义是本地的; 没有要求同一个方法的名称意味着相同的 事情为一个不相关的类。相比之下,R中的方法定义并不是 驻留在类定义中;从概念上讲,它们与通用 函数相关联。类定义直接进入确定方法选择,直接 或通过继承。使用面向对象编程模型有时 沮丧或困惑,他们的节目不会直接转移到R, 但它不能。所述功能使用的方法比较复杂,但可以具有有意义的功能也 更切合,并且不能被降低到 OOP版本。

13

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

#' 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='')) 
} 

和一些测试代码:

test <- EmailClass(name="Jason", "[email protected]") 
    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("[email protected]") 
    test$getHistory() 
    test$sendMail("[email protected]") 
    test$getNumMessagesSent() 

    test2 <- EmailClass("Nobody", "[email protected]") 
    test2 
    test2$props 
    test2$getHistory() 
    test2$sendMail('[email protected]') 

这里是一个博客帖子我写的这个做法的链接:http://bryer.org/2012/object-oriented-programming-in-r我欢迎评论,批评和建议,因为如果这是最好的方法,我不相信自己。但是,对于我试图解决的问题,它效果很好。特别是,对于makeR软件包(http://jbryer.github.com/makeR),我不希望用户直接更改数据字段,因为我需要确保表示对象状态的XML文件保持同步。只要用户遵守我在文档中概述的规则,就可以很好地工作。

+10

你有点用上面的代码“手动”重新创建参考类...它只是让事情变得更加脆弱。 – 2012-03-07 19:09:54

+0

谢谢西蒙。直到我发布这个消息之后,我才意识到ReferenceClasses。 – jbryer 2012-03-09 13:56:32