我有两个简单的类:
.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”初始化程序有什么问题,有什么想法吗? 谢谢!
答案 0 :(得分: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,以避免出现超过几个插槽的组合问题。
另一种方法,似乎是在实践中采用的方法,即使它实际上只是侧面解决问题,是避免使用初始化方法,而是依赖于单独的构造函数来进行任何数据按摩,如此答案的Retaining copy construction部分的第一个代码框。