Dear R-Users and R-Devels,
I am struggling with the method dispatch for S4 objects. First I will give a
simple example to make clear what the general setting in my project is.
Three classes will be build in the example: A is just a simple class. B
contains A in a slot and C inherits from B. In addition all classes have a slot
called "specA", "specB", specC" that should be computed during initialization
by calling the method "generateSpec" defined for each class A,B,C:
## Define class A##
setClass("A", representation(a = "numeric", specA = "numeric"))
setMethod("initialize", "A", function(.Object, value){.Object@a <- value;
.Object <- generateSpec(.Object); return(.Object)})
setGeneric("generateSpec", function(object) standardGeneric("generateSpec"))
setMethod("generateSpec", "A", function(object) {object@specA <- 1/object@a;
return(object)})
## Define class B containing A in a slot ##
setClass("B", representation(b = "numeric", specB = "numeric", A = "A"))
setMethod("initialize", "B", function(.Object, value = 0){.Object@b <- value;
.Object@A <- new("A", value = value); .Object <- generateSpec(.Object);
return(.Object)})
setMethod("generateSpec", "B", function(object) {aSpec <- object@A@specA;
object@specB <- 1/aSpec; return(object)})
## all fine:
new("B", value = 2)
## Define class C inheriting from class B ##
setClass("C", representation(c = "numeric", specC = "numeric"), contains=c("B"))
setMethod("initialize", "C", function(.Object, value) {.Object@c <- value;
.Object <- callNextMethod(.Object, value); .Object <- generateSpec(.Object);
return(.Object)})
setMethod("generateSpec", "C", function(object) {bSpec <- object@specB;
object@specC <- 1/bSpec; return(object)})
## numeric(0) for specB and specC
new("C", value = 2)
Note, that the "generateSpec" method of B depends on the "specA" slot of A, the
"generateSpec" method of class C depends on the "specB" slot of class B. Note
also, that in the "initialize" method of B one has to give the "value" argument
a default value. When calling the last line of code, "specB" and "specC" are
numeric(0). As the slot "b" of the new "C" class is equal to 2, the
"initialize" method of class B is called but the ".Object" in the "initialize"
method of class B is an object of class C. And of course in this case method
dispatching chooses the "generateSpec" method of class C - "generateSpec" for
class B gets never called. In general this is exactly what we want, when
inheriting classes: dispatching makes OOP programming not only simpler, but
actually possible.
My question: How can I make this setting work? How can I generate an
"initialize" method for class B that calls ALWAYS the "generateSpec" method of
class B (using "as" lets me end up in the "initialize" method of class C with
an object of class B as it is only possible to convert a derived object to its
base class but not the other way around)?
Best
Simon
______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.