There is two classes A & B.
B extends A.
There is a method doStuffs
for A and one for B.
They have same name and signature except they work on different object and accordingly they do different stuffs.
setClass(
Class = "A",
slots = list(
a = "character",
b = "character"
)
)
setGeneric("doStuffs", signature ="obj",
function(obj,...) standardGeneric("doStuffs")
)
setClass(
Class = "B",
contains = "A",
slots = list(
c = "character"
)
)
setGeneric("doStuffs", signature ="obj",
function(obj,...) standardGeneric("doStuffs")
)
When I call :
obj <- new A(a="a",b="b")
showMethods("doStuffs")
doStuffs(obj)
Function: doStuffs (package blahblah)
obj="B"
unable to find an inherited method for function ‘doStuffs’ for signature ‘obj = "A"’
If I use the following code for both generics, it works.
Don't know why.
showMethods find both generics.
if (!isGeneric("doStuffs")) {
if (is.function("doStuffs")) {
fun <- doStuffs
} else {
fun <- function(obj, ...) standardGeneric("doStuffs")
}
Function: doStuffs (package blahblah)
obj="A"
obj="B"
Why does this work ? How to code this the "good way" ?
Updated : I also have doStuffs method for each classes:
setMethod("doStuffs", "A", function(obj, x1,x2,x3) {}
setMethod("doStuffs", "B", function(obj, x4,x2,x3) {}
As discussed in comments, you are misusing setGeneric
(and not using setMethod
).
Based on the class definitions you provide, first define the generic:
setGeneric(
"doStuffs",
function(obj,...) standardGeneric("doStuffs")
)
"doStuffs"
Now define a couple of objects
obj1 <- new ("A", a = "A", b = "B")
obj2 <- new ("B", a = "C", b = "D")
Next, define a method for the superclass ...
setMethod(
"doStuffs",
signature = signature(obj = "A"),
def = function(obj) {
"Hello from A"
}
)
... and see what happens:
doStuffs(obj1)
[1] "Hello from A"
doStuffs(obj2)
[1] "Hello from A"
This is correct: there is no doStuffs
method for the subclass, so objects of the subclass use the method of the superclass.
Now define a method for class B
...
setMethod(
"doStuffs",
signature = signature(obj = "B"),
def = function(obj) {
"Hello from B"
}
)
... and repeat.
doStuffs(obj1)
[1] "Hello from A"
doStuffs(obj2)
[1] "Hello from B"
All good.
I think the S4 Chapter of Hadley's Advanced R is well worth a read. And several re-reads.