Skip to content
Prev 39706 / 63424 Next

super basic questions about S4 classes

Hi Andre,

1. Keep in mind that a S4 method belongs to a specific generic function,
not to a specific object or class. There is none such thing as a "class
member function" in the S4 system. As an example for illustration,
consider the following class definitions in Java:

class myClassA
{
    int a;
    int myMethod();
}

class myClassB
{
    double b;
     int myMethod()
}

Assuming that myClassA and myClassB are not related by inheritance, the
two instances of "myMethod" have nothing to do with each other. With S4
classes, you would have something like:

setClass("myClassA", representation(a="integer"))
setClass("myClassB", representation(b="numeric"))

setGeneric("myMethod", function(x) standardGeneric("myMethod"))
setMethod("myMethod", "myClassA", function(x) {"myMethodA"})
setMethod("myMethod", "myClassB", function(x) {"myMethodB"})

where the instances of myMethod belong to the same generic function.
Note that because the methods do not belong to a specific class /
object, the object on which to call must be passed as argument.
Futhermore, it is impossible to have a method with a different argument
list than the generic. Based on the code above, the following gives an
error:

setClass("myClassC", representation(c="character"))
setMethod("myMethod", "myClassC", function(x,y) {"myMethodC"})

while in Java it is no problem to have

class myClassC
{
    char c[];
    int myMethod(int x, int y)
}

with a different argument list for myMethod.

(Of course, different argument lists in methods are possible if one uses
"..." in the generic, this example was just meant as an illustration of
the conceptual difference between class methods and generic functions.)

There is a new approach in R called "reference classes", which might
provide what you are looking for. But I am not familiar with this
paradigm. See ?ReferenceClasses.

2. A function in R is stored in a variable of the same name - as there
can be only one variable with a distinct name (within the same scope),
no overloading is possible. What I usually do is to provide all possible
arguments and check which ones are missing (via missing()) to determine
which to use to construct the object. Another possibility would be to
make the constructor a method which dispatches on the parameter types.

3. S4 methods can be debugged with trace(), to which a method name and a
signature can be passed. I think there is an item in the FAQ about this.
There is one peculiarity with debugging if you have a method that has
additional arguments compared to the generic, for example:

setGeneric("myMethod", function(x, ...) standardGeneric("myMethod"))
setMethod("myMethod", "myClassA", function(x,y) {"myMethodA"})

In this case, the implementation for myMethod will define and call an
inner function ".local". In order to trace into this function, you have
to call debug(.local) from the browser once the method has been traced.


Hope this helps,

Andreas



A Zege schrieb: