1

我有两个简单的类:

.A1 <- setClass("A1", 
            representation=representation( x1 ="numeric"),
            prototype = prototype(x1 = 10))

.A2 <- setClass("A2", contains="A1",
           representation=representation(x2="numeric"),
           prototype = prototype(x2 = 10))

setMethod("initialize", "A2",
      function(.Object, ..., x2 = .Object@x2)
      {
        callNextMethod(.Object, ..., x2 = x2)
      })

使用此代码一切正常:

a1 <- .A1(x1 = 3)
initialize(a1)

a2 <- .A2(x1 = 2, x2 = 4)
initialize(a2, x2 = 3)

.A2(a1, x2 = 2)

An object of class "A2"  # WORKS!
Slot "x2":
[1] 2

Slot "x1":
[1] 3

特别是最后一行工作,因此 a1 被复制到“A2”对象中。问题是,如果还为基类定义“初始化”,最后一行将不再起作用:

setMethod("initialize", "A1",
      function(.Object, ..., x1 = .Object@x1)
      {
        callNextMethod(.Object, ..., x1 = x1)
      })

## I have to redefine also this initializer, otherwise it will call
## the default initializer for "A1" (it was stored in some lookup table?)
setMethod("initialize", "A2",
      function(.Object, ..., x2 = .Object@x2)
      {
        # your class-specific initialization...passed to parent constructor
        callNextMethod(.Object, ..., x2 = x2)
      })

现在我得到:

.A2(a1, x2 = 2)
An object of class "A2"  # BAD!
Slot "x2":
[1] 2

Slot "x1":
[1] 10

我想我的“A1”初始化程序有问题,有什么想法吗?谢谢!

4

1 回答 1

2

A1 的初始化方法行为不端,因为x1 = .Object@x1咨询 .Object,它对于构造函数是类的原型(对于您的示例.A2(a1, x2=2),在初始化中,A1 方法 .Object 是从 A2 的原型构造的,因此 x1 分配为 10,并且 x1 = .Object@x1 = 10 会覆盖 a1 提供的值。

很难知道什么是通用解决方案。你可以测试缺失

setMethod("initialize", "A1", function(.Object, ..., x1) {
    if (!missing(x1))
        callNextMethod(.Object, ..., x1=x1)
    else 
        callNextMethod(.Object, ...)
})

或者做一些聪明的事情,也许使用 match.call,以避免超过几个插槽的组合问题。

另一种方法似乎是实践中采用的方法,尽管它实际上只是回避了问题,是避免使用初始化方法,而是依赖单独的构造函数来进行任何数据按摩,如第一个代码框此答案的保留副本构造部分的。

于 2013-08-15T22:43:08.730 回答