有没有一种方法可以初始化S4对象,以便返回另一个对象?

3

我有一个类层次结构,其中超类fb不应存在对象(我尝试过虚拟类,但遇到了无法从虚拟类初始化对象的问题)。此外,我有两个子类(foobar)具有相同的插槽。现在,我想使用一个初始化方法将基于某些值返回一个子类对象的超类来创建一个新对象:

setClass("fb", representation( x = "numeric"))

setClass("foo", contains = "fb")
setClass("bar", contains = "fb")

setMethod("initialize", "fb", function(.Object, x) {
    if (x < 5) class(.Object) <- "foo"
    else class(.Object) <- "bar"
    .Object@x <- x
    .Object
})

> new("fb", x = 3)
Error in initialize(value, ...) : 
  initialize method returned an object of class "foo" instead of the required class "fb"

显然(并且可能有很好的理由)R 不允许这样做。在方法内部实现我所需求的功能而不使用 if-else 结构来创建新对象,是否有办法实现?
1个回答

4
S4帮助我们在规定范围内着色。因此,您的fb类应该是虚拟的,您的initialize方法不应更改.Object的类。您可以编写一个名为fb的函数,以执行条件实例化。
setClass("fb", representation( x = "numeric", "VIRTUAL"))
setClass("foo", contains = "fb")
setClass("bar", contains = "fb")

fb <-
    function(x)
{
    if (x < 5) new("foo", x=x)
    else new("bar", x=x)
}

fb是一个构造函数,对于用户来说更加方便,并将您的类层次结构与其实现分离,这通常被认为是一件好事。

值得一提的是,S4 initialize 方法的一个隐含约束是new("foo")(使用类名但没有其他参数调用new)必须起作用(否则在尝试扩展foo时会失败)。因此,initialize方法的范例应该如下:

setMethod(initialize, "foo", function(.Object, ..., x=1) {
    .Object <- callNextMethod(.Object, ...)
    .Object@x <- x
    .Object
})

虽然通常情况下(例如在这种情况下,initialize 只是进行插槽分配),根本不需要初始化方法。请注意使用 ...x 的定位(要求在相应的 new 调用中命名参数)以及默认值的使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接