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.wick...@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/ ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.