[R] inheritence in S4
Christophe Genolini
cgenolin at u-paris10.fr
Thu Mar 6 00:40:23 CET 2008
Hi Martin
I was not that much speaking about what we can do, but more about what
we can't. We can't decide that object will be 'never empty', we have to
allow empty oject, otherwise new("A") will not work and that will be
problematic.
So, at this point, I see :
- it is necessary to allow the creation of empty object (otherwise, we
are in trouble with 'as')
- so 'new' will have to create object either empty or valid.
- 'initialize' can check if an object is valid but has first to check
if the object is non empty
- I create an object Ccc containing an object Aaa : If Ccc is calling
the constructor of Aaa, then initialize of Aaa ic called. If Ccc is
setting the Aaa slot one bu one, the initialize of Aaa is not caller.
- In addition, I did not speak about the setteur, but the 'setSlotX
<-' does not call the initialize. So we have to check the validity of
the object after any 'setSlot' again.
In consequence, to program as safe as possible:
- for checking if an object is valid or not, I am thinking of setting
a method checkCoherance
- 'initialize' will just set slot to either empty or some value, then
call checkCoherance
- 'setSlotX<-' will change slot X, then call checkCoherance
- If I create a C object, its checkCoherance method will call
checkCoherance(as(object,"A"))
Here is an example (still the same stupid example with a single slot.
Obviously, it has no interest on so small object, it is just to simplify)
--- 8< ------------------
setGeneric("checkCoherance",function(object){standardGeneric("checkCoherance")})
setClass("A", representation(x="numeric"))
setMethod("checkCoherance","A",
function(object){
cat("*** checkCoherance A ***\n")
if(length(object at x)>0){
if(object at x<0){stop("Object incoherance : x should be
positive")}else{}
}else{}
return(TRUE)
}
)
setMethod("initialize","A",
function(.Object,value=numeric(0)){
cat("*** initialize A ***\n")
.Object at x <- value
checkCoherance(.Object)
return(.Object)
}
)
setGeneric("setX<-",function(object,value){standardGeneric("setX<-")})
setReplaceMethod("setX","A",
function(object,value){
object at x <- value
checkCoherance(object)
return(object)
}
)
a1 <- new("A")
a2 <- new("A",value=4)
try(a3 <- new("A",value=-4))
A <- function(val=numeric(0)){
new("A",value=val)
}
A()
A(val=4)
A(val=-4)
setClass("C", representation(y="numeric"),contains="A")
setMethod("checkCoherance","C",
function(object){
cat("*** checkCoherance C ***\n")
if(length(object at y)>0){
if(object at y>0){stop("Object incoherance : y should be
négative")}else{}
}else{}
checkCoherance(as(object,"A"))
return(TRUE)
}
)
setMethod("initialize","C",
function(.Object,valueX=numeric(0), valueY=numeric(0)){
cat("*** initialize C ***\n")
.Object at x <- valueX
.Object at y <- valueY
checkCoherance(.Object)
return(.Object)
}
)
c <- new("C",valueX=10,valueY=12)
new("C")
C <- function(valX=numeric(0),valY=numeric(0)){
new("C",valueX=valX,valueY=valY)
}
C()
C(valX=5)
try(C(valX=-5))
C(valY=-3)
c1 <- C(valX=4,valY=-6)
as(c1,"A")
--- 8< ------------------
> You're partly misunderstanding...
>
>
Lol. I guess so, and unfortunatly, it is not over ...
> setClass("A", representation(x="numeric"),
> prototype=prototype(x=0))
>
>
I do not understand the difference with
setClass("A", representation(x="numeric"),
prototype(x=0)
)
> If you have an initialize
> method on "A" then it will be called.
Only if you call the A constructor, right ? Not if you set the slot that
C has heritate from A one by one, right ?
Christophe
More information about the R-help
mailing list