The A1 initialize method mis-behaves because x1 = .Object@x1
consults .Object, which for the constructor is the prototype of the class (for your example .A2(a1, x2=2)
, in the initialize,A1-method .Object is constructed from the prototype of A2, so x1 is assigned 10, and x1 = .Object@x1 = 10 over-writes the value provided by a1.
It's hard to know what a general solution is. You could test for missing-ness
setMethod("initialize", "A1", function(.Object, ..., x1) {
if (!missing(x1))
callNextMethod(.Object, ..., x1=x1)
else
callNextMethod(.Object, ...)
})
or do something clever, maybe with match.call, to avoid a combinatorial problem with more than a couple of slots.
Another approach, which seems to be the one adopted in practice even though it really just side-steps the problem, is to avoid using an initialize method, and instead rely on a separate constructor to do any data massaging, as in the first code box of the Retaining copy construction section of this answer.