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

______________________________________________
R-help@r-project.org 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.

Reply via email to