Oop 是否有方法为S4引用类声明公共和私有方法?

Oop 是否有方法为S4引用类声明公共和私有方法?,oop,r,encapsulation,public-method,private-methods,Oop,R,Encapsulation,Public Method,Private Methods,前面:我知道R是一种函数式语言,所以请不要咬;-) 在我的许多程序中使用OOP方法时,我都有过很好的经验。 现在,我想知道在R中使用公共方法和私有方法时是否有区别 例子 类定义 注意 我通常不会将实际的方法定义放在类def中,而是将其与S4方法分开(即thisIsPublic_ref),原因如下: 这样,类def保持清晰的排列,并且在单个方法def变得相当大的情况下更易于阅读 它允许您随时切换到方法的函数执行。如果x是某个类的实例,则可以调用foo\u ref(.self=x)而不是x$foo(

前面:我知道R是一种函数式语言,所以请不要咬;-)

在我的许多程序中使用OOP方法时,我都有过很好的经验。 现在,我想知道在R中使用公共方法和私有方法时是否有区别

例子 类定义 注意

我通常不会将实际的方法定义放在类def中,而是将其与S4方法分开(即
thisIsPublic_ref
),原因如下:

  • 这样,类def保持清晰的排列,并且在单个方法def变得相当大的情况下更易于阅读
  • 它允许您随时切换到方法的函数执行。如果
    x
    是某个类的实例,则可以调用
    foo\u ref(.self=x)
    而不是
    x$foo()
  • 它允许您通过
    编译器::cmpfun()
    对方法进行字节编译,我认为如果您有“普通”引用类方法,这是不可能的
  • 对于这个具体的例子来说,把它弄得这么复杂确实没有意义,但我想我还是要说明一下这种方法

    方法定义 实例 类
    A
    (即
    x.A
    )的实例不应被允许使用类
    B
    私有方法。因此,我希望此不起作用,即导致错误:

    > x.a$a.1$thisIsPrivate()
    [1] TRUE
    
    你知道怎么能说明这一点吗

    到目前为止,我唯一想到的是:


    向每个方法添加
    sender
    参数,为每个方法调用显式指定它,并检查
    class(.self)=class(sender)
    。但这似乎有点“明确”。

    简单的答案是制作一个包。它的分区方式代码(名称空间)比Java类语言中的等价物更为独立

    制作包时,可以使用指令
    export
    exportMethods
    指定在名为NAMESPACE的文件中导出的内容。可以选择不导出希望为包私有的方法和其他R对象(使用Java术语)。请参阅

    第一次做一个软件包很难,但是有很多帮助。请参阅上面链接的文档和编写R扩展手册


    确保引用类是您真正想要的。无论值多少钱,常规S4类通常都是R-ish的方式。关于R的许多OO构造(以及包装)的大量信息源已打开。

    由于函数是R中的一流对象,您可以将一个嵌入另一个,如下所示:

    hello <- function() {
        print_ <- function() { 
             return ('hello world')
        }
        print_()
    }
    

    hello x.a是类a的实例,但x.a$a.1是类B的实例。你想阻止类B的实例访问类B的私有方法吗?你可能会进入一个痛苦的世界,试图阻止类访问它的方法是基于它可能生活在什么样的数据结构中…完全正确,而且这不是我的目标。同样,这是一个主题,我觉得我只是缺少一些关于OOP的背景知识。将某些类的实例放在其他类的字段中(即
    x.a$a.1
    作为类
    a
    x.a
    中的类
    B
    的实例)这是我实现某种程度的封装的方式。但是你完全正确,这种方式实际上不可能区分公共方法和私有方法,因为最终调用该方法的是
    a.1
    ,而不是
    x.a
    。我会考虑对我的示例进行一个很好的更新,以使事情更清楚。我完全同意同意这一点,软件包是一个不错的选择。但是,请注意,不从软件包中导出某些内容并不意味着用户无法访问它。您仍然可以访问“private”函数和数据使用“
    ”运算符。我认为这一点都不厚颜无耻。这是javascript库中的标准做法,在其他面向函数的脚本语言中看到它也不会感到惊讶。
    x.b <- new("B", b.1=10, b.2=TRUE)
    x.a <- new("A", a.1=x.b, a.2="hello world")
    
    > x.a$a.1$thisIsPublic()
    [1] 10000
    
    > x.a$a.1$thisIsPrivate()
    [1] TRUE
    
    hello <- function() {
        print_ <- function() { 
             return ('hello world')
        }
        print_()
    }