假设您有一个S4类“A”,以及一个具有附加功能的子类“B”.每个都有自己的有效性检查 – B应该只检查其他功能.现在在B的初始化中,我想从A类的对象开始,然后用附加功能修改它.然而
这是虚拟代码:
setClass(Class="A", representation= representation(x="numeric"), validity= function(object){stopifnot(x > 0)}) setMethod("initialize", signature(.Object="A"), function(.Object, ..., z){ x <- get("z") + 1 callNextMethod(.Object, ..., x=x) }) setClass(Class="B", contains="A", representation= representation(y="numeric"), validity= function(object){stopifnot(y > 0)}) setMethod("initialize", signature(.Object="B"), function(.Object, ..., bla){ .Object <- callNextMethod(.Object, ...) .Object@y <- .Object@x + bla return(.Object) }) test <- new("B", z=4, bla=5)
如果我尝试创建“测试”对象,我得到:
Error in stopifnot(x > 0): object 'x' not found
你知道我怎么能做得更好吗?
非常感谢提前!
最好的祝福
丹尼尔
> validObject(new("A")) Error in get("z") : argument "z" is missing, with no default
一个选项将在initialize方法中为z提供默认值,或者(我的偏好)在类定义中使用原型并与构造函数结合使用.此外,有效性函数应返回TRUE(如果有效)或描述其无效的字符向量.所以我写了你的班级’A’
.A <- setClass(Class="A", representation(x="numeric"), prototype(x=1), validity= function(object) { msg <- NULL if (length(object@x) != 1 || object@x <= 0) msg <- c(msg, "'x' must be length 1 and > 0") if (is.null(msg)) TRUE else msg })
(setClass()的返回值只是在一个语义更丰富的函数调用中包装new()).
> validObject(.A()) [1] TRUE
而不是使用initialize方法(这是正确实现的棘手 – 它也是一个复制构造函数)我写
A <- function(z, ...) .A(x=z+1, ...)
其行为与预期一致
> A() Error in initialize(value, ...) (from valid.R!7685pfr#2) : argument "z" is missing, with no default > A(1) An object of class "A" Slot "x": [1] 2
我认为将这些原则扩展到“B”应该是直截了当的,并且是一个很好的“读者练习”!