我在虚拟/抽象类中找不到太多help(ReferenceClasses)
- 任何人都可以提供创建一个基本示例吗?此外,如何指定虚拟方法并强制子类必须实现它?
问问题
1457 次
2 回答
6
参考类是 S4 类。所以也许你应该看到setClass
and的帮助Classes
:
这是一个虚拟示例:
# virtual Base Class
setRefClass(
Class="virtC",
fields=list(
.elt="ANY"
),
methods = list(
.method = function(){
print("Base virtual method is called")
}
),
contains=c("VIRTUAL")
)
## child 1
## field as numeric and base .method is used
setRefClass(
Class="childNum",
fields=list(
.elt="numeric"
),
contains=c("virtC")
)
## child 2
## field is char and .method is overwritten
setRefClass(
Class="childChar",
fields=list(
.elt="character"
),
methods = list(
.method = function(){print('child method is called')}
),
contains=c("virtC")
)
## new('virtA') ## thros an error can't isntantiate it
a = new("childChar",.elt="a")
b = new("childNum",.elt=1)
b$.method()
[1] "Base virtual method is called"
a$.method()
[1] "child method is called"
于 2014-01-15T16:50:49.157 回答
1
这是我正在考虑采用的一种方法,用于从继承的虚拟“接口”中捕获未实现的方法。它不会静态捕获不正确的实现,但如果您尝试实例化一个没有实现所有接口方法的对象,它会出错。与其在调用未实现的函数时等待运行时错误,不如在您尝试创建对象时立即炸弹。
辅助函数
用于在继承树中搜索接口的辅助函数。现在这个太基础了。我需要做的是爬树并检查自己继承接口类的父母......
.get_interface_methods <- function(.self) {
## Get the environment of the class being instantiated
env <- attributes(.self$.refClassDef)$refMethods
## get original interface methods
supers <- selectSuperClasses(class(.self))
methods <- unlist(lapply(supers, function(x) getRefClass(x)$methods()))
## check the body is NOT null in the concrete class environment
funs <- Filter(is.function, lapply(methods, get, envir=env))
null_fun_body <- vapply(Map(body, funs), is.null, T)
## return names of functions not implemented
vapply(funs[null_fun_body], attr, "", which="name")
}
在实例化包含一个或多个接口的对象时调用的另一个辅助函数。
.validate_interface <- function(.self) {
methods <- get_interface_methods(.self)
## stop the world and print out the un-implemented methods
if (length(methods) > 0L) {
stop("Must implement interface methods: ", paste(methods, collapse = ", "))
}
}
课程
Interface 类只是在初始化期间调用 validate 函数。从 Interface 继承的类可以使用任何具有NULL
主体的函数注册接口方法。我为此创建了一个简单的助手。
setRefClass(
"Interface",
methods = list(
initialize = function() {
validate(.self)
}), contains="VIRTUAL")
InterfaceMethod <- function() NULL
接口
NULL
在这里,我使用具有主体的虚拟方法创建了两个接口。
## Create an interface to be implemented
setRefClass(
"ITest1",
contains=c("VIRTUAL", "Interface"),
methods = list(
foo = InterfaceMethod,
bar = InterfaceMethod,
baz = InterfaceMethod
))
## create a second interface
setRefClass(
"ITest2",
contains=c("VIRTUAL", "Interface"),
methods = list(
spam = InterfaceMethod,
ham = InterfaceMethod
))
实例化一个对象
最后,我创建了一个非虚拟的类定义,它继承了我定义的两个接口。在定义中,我实现了两个接口函数foo
&baz
但没有实现bar
, spam
, or ham
:
Obj <- setRefClass(
"Obj",
contains = c("ITest1", "ITest2"),
methods = list(
foo = function() "Implemented!",
baz = function() "Implemented!"
))
当我尝试实例化这个对象时,我得到一个错误。
> x <- Obj$new()
Error in validate(.self) :
Must implement interface methods: bar, ham, spam
于 2018-09-12T21:28:03.050 回答