Search code examples
rr-s3

Call overridden s3 method from subclass (R.oo / R.methodsS3)


I'm using setMethodS3 in package R.methodsS3 to create an S3 method. Lets say I have two classes, class Parent and class Child (R.oo object). class Child inherits from class Parent. Both have the method MyMethod(). How do I call superclass MyMethod() (Parent's MyMethod) from Child's MyMethod()? I tried this$MyMethod(), but it calls Child's MyMethod()

Here's a reduced example:

library( R.oo )

setConstructorS3( "Parent" , definition = 
function()
{
    extend( Object() , "Parent" , .stateVar1 = FALSE )
} )

setMethodS3( "MyMethod" , "Parent" , appendVarArgs = FALSE , definition = 
function( this , someParam , ... )
{
   print( this$.stateVar1 )
   print( someParam  )
} )

setConstructorS3( "Child" , definition = 
function()
{
    extend( Parent() , "Child" )
} )

setMethodS3( "MyMethod" , "Child" , appendVarArgs = FALSE , definition = 
function( this , someParam , ... )
{
   NextMethod( "MyMethod" ) # does not work
   this$MyMethod( someParam ) # also does not work
} )

child = Child()
child$MyMethod()

Solution

  • You do want to use NextMethod() to achieve this. NextMethod() will work if you use MyMethod(child), which I strongly recommended.

    The fact that is does not work with the child$MyMethod() seems to be a bug of the Object class. I'll look into it. I think this bug has passed unnoticed because the <object>$<method>() construct is so rarely used by anyone. The MyMethod(child) construct is standard R. We use it in all our code (>100,000 lines). Honesty, I wish I never wrote about child$MyMethod() in the R.oo paper (2003).

    Finally, although not required, I recommend that you use the RCC convention using CapitilizedNames for classes and nonCapitalizedNames for methods and objects, setMethodS3("myMethod", "Child", ...).

    /Henrik (author of R.methodsS3 and R.oo)