Documentation of S3 and S4 classes, inheritance
On 5/23/05, Ross Boylan <ross at biostat.ucsf.edu> wrote:
I'd like to have a class A that computes a likelihood, and a subclass B that computes the same likelihood by sometimes throws in an additional term (B includes measurement error). So B's likelihood needs to call A's, and then (sometimes) multiply by an additional term. It sounds as if, in the S3 scheme, NextMethod is supposed to do this: like.A <- function(stuff) compute value like.B <- function(stuff) extraFactor*NextMethod() ?
Here is a working example to try out. In the call to lik,
the first class in the class vector is "B" so lik.B gets invoked.
The next method of x is "A" so NextMethod invokes lik.A from
within lik.B and then returns its result to lik.A which finishes the
calculation.
lik <- function(x) UseMethod("lik")
lik.A <- function(x) mean(x)
lik.B <- function(x) NextMethod("lik") + sd(x)
x <- structure(1:3, class = c("B", "A"))
lik(x) # 3
but, after some study of both the Language Manual (2.1) and the online
help of NextMethod I can't tell exactly what it does. In particular,
I'm not sure if it returns to the calling function, or how it decides
which flavor to call. The language manual says the method choice
depends on the values of .Generic and .Class, but doesn't say how those
get filled in. I would expect .Class to be the current class, in which
case the call is recursive. The online help says "'NextMethod' invokes
the next method (determined by the class)" but it doesn't say how it is
determined. One ambiguity is whether "class" refers to the class (B) or
the class attribute ("B", "A").
See above discussion.
I think the documentation could be clearer. Now, probably none of this matters to me, since several sources (including the online help for S3)indicate that S4 classes are preferred. I found the documentation for S4 initially elusive. As far as I can tell, it isn't even mentioned in the "R Language Definition." While the fact that S4 is defined in a package makes clear it is not formally part of the base language, this is not a very good way to get people to use S4. I think by now I've tracked down docs on S4, including the intro/overview at http://www.omegahat.org/RSMethods/. Finally, I'm a bit concerned that one article mentioned that S4 inheritance, in practice, is used mostly for data, not methods (Thomas Lumley, R News 4(1), June 2004: p. 36). Am I going down a road I shouldn't travel?
This area seems somewhat controversial with different people stating different opinions. IMHO you are probably best off to start with S3 since its simpler and if you do learn S4 later they are not unrelated so it will make it easier than jumping straight into it. Also you may find you never have to go beyond S3 in which case you have saved yourself some time. I personally use S3. By the way if choosing from S3 and S4 is not enough, there are also two CRAN packages that provide additional OO models as well: R.oo and proto.