[R] Understanding S4 method dispatch

Simon Zehnder szehnder at uni-bonn.de
Tue Aug 13 17:10:33 CEST 2013


If you take an example which works with slots,

setClass("A", representation(a = "numeric")
setClass("B", contains = c("A"), representation(b = "numeric"))
a <- new("A", a = 2)
b <- new("B", a = 3, b = 2)

setClass("AB", contains = c("A", "B"))
new("AB", a = 2, b = 3)

You see, that there is only one @a slot, the one inherited from B, that B inherits from A. If this were not the case, which slot should be taken, if we would call @a? To avoid this kind of ambiguity, only one A class is inherited to AB: the one B already inherits from A. 

You could create a class, that contains another A object in a slot:

setClass("AandB", contains = c("B"), representation(A = "A"))
new("AandB", a = 2, b = 3, A = new("A", a = 3))

Now back to your example: as there is only one A object inside the B object which is contained by the AB object, method dispatch works the way as it should: It looks for a method f for an AB object. It does not find one. Then it looks for a method f for the contained B object (as this is the only one contained in AB) and it finds a method. Then it calls this method on the B part of the object AB and the result is "B-B"

Best

Simon



On Aug 13, 2013, at 4:24 PM, Hadley Wickham <h.wickham at gmail.com> wrote:

>> The class AB inherits from A and from B, but B already inherits from class A. So actually you only have an object of class B in your object of class AB. When you call the function f R looks for a method f for AB objects. It does not find such a method and looks for a method of the object inherited from, B. Such a method is present and is then executed.
>> 
>> The inheritance structure has to be changed. The behavior is actually desired, as if this behavior weren't given a diamond class inheritance would be fatal.
> 
> Are you sure? That behaviour doesn't agree with the description of
> method dispatch given in ?Methods, not with getClass("AB") which shows
> that AB inherits from both A and B. (I totally agree that this is a
> bad idea, and unlikely to be useful in real life, but I'm trying to
> understand the details of S4 dispatch)
> 
>> getClass("AB")
> Class "AB" [in ".GlobalEnv"]
> 
> Slots:
> 
> Name:  .xData
> Class:   NULL
> 
> Extends:
> Class "B", directly
> Class "A", directly
> Class ".NULL", by class "A", distance 2
> Class "NULL", by class "A", distance 3, with explicit coerce
> Class "OptionalFunction", by class "A", distance 4, with explicit coerce
> Class "optionalMethod", by class "A", distance 4, with explicit coerce
> 
> -- 
> Chief Scientist, RStudio
> http://had.co.nz/



More information about the R-help mailing list