预先:我知道 R 是一种函数式语言,所以请不要咬 ;-)
在我的许多程序中使用 OOP 方法时,我有很好的经验。现在,我想知道在 R 中使用S4 引用类时是否有办法区分公共方法和私有方法?
例子
类定义
setRefClass("B",
field=list(
b.1="numeric",
b.2="logical"
),
methods=list(
thisIsPublic=function(...) {
thisIsPublic_ref(.self=.self, ...)
},
thisIsPrivate=function(...) {
thisIsPrivate_ref(.self=.self, ...)
}
)
)
setRefClass("A",
field=list(
a.1="B"
)
)
笔记
我通常不会将实际的方法定义放在类 def 中,而是将其与 S4 方法(即thisIsPublic_ref
)分开,原因如下:
- 这样,类 def 保持清晰的排列,并且在单个方法 def 变得非常大的情况下更易于阅读。
- 它允许您随时切换到方法的功能执行。作为
x
某个类的实例,您可以调用foo_ref(.self=x)
而不是x$foo()
. compiler::cmpfun()
如果您有“普通”参考类方法,它允许您对我认为不可能的方法进行字节编译。
对于这个具体的例子来说,把它弄得那么复杂肯定没有什么意义,但我想我还是会说明这种方法。
方法定义
setGeneric(
name="thisIsPublic_ref",
signature=c(".self"),
def=function(
.self,
...
) {
standardGeneric("thisIsPublic_ref")
}
)
setGeneric(
name="thisIsPrivate_ref",
signature=c(".self"),
def=function(
.self,
...
) {
standardGeneric("thisIsPrivate_ref")
}
)
require(compiler)
setMethod(
f="thisIsPublic_ref",
signature=signature(.self="B"),
definition=cmpfun(function(
.self,
...
){
.self$b.1 * 1000
})
)
setMethod(
f="thisIsPrivate_ref",
signature=signature(.self="B"),
definition=cmpfun(function(
.self,
...
){
.self$b.2
})
)
实例
x.b <- new("B", b.1=10, b.2=TRUE)
x.a <- new("A", a.1=x.b, a.2="hello world")
公共与私人
应该允许class A
(ie )的实例使用 class的公共方法:x.a
B
> x.a$a.1$thisIsPublic()
[1] 10000
不应允许class A
(ie x.a
)的实例使用 class的私有方法。所以我希望这不起作用,即导致错误:B
> x.a$a.1$thisIsPrivate()
[1] TRUE
知道如何指定这一点吗?
到目前为止我唯一想到的:
为每个方法添加一个sender
参数,为每个方法调用显式指定它并检查 if class(.self) == class(sender)
。但这似乎有点“明确”。