Oop 是否有方法为S4引用类声明公共和私有方法?
前面:我知道R是一种函数式语言,所以请不要咬;-) 在我的许多程序中使用OOP方法时,我都有过很好的经验。 现在,我想知道在R中使用公共方法和私有方法时是否有区别 例子 类定义 注意 我通常不会将实际的方法定义放在类def中,而是将其与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(
thisIsPublic_ref
),原因如下:
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_()
}