Skip to main content

Overriding an Inherited Method

Overriding an Inherited Method

A class inherits methods (both class and instance methods) from its superclass or superclasses. Except for methods that are marked Final, you can override these definitions by providing a definition within this class. If you do so, note the following rules:

  • If the method is a class method in the superclass, you cannot override it as an instance method in the subclass, and vice versa.

  • The return type of the subclass method must be either the same as the original return type or a subclass of the original return type.

  • The method in the subclass can have more arguments than the method in the superclass. (Also see the “Number of Arguments” subsection.)

  • The method in the subclass can specify different default values for the arguments.

  • The types of the arguments in the subclass method must be consistent with the types of the arguments in the original method. Specifically, any given argument must be either the same as the original type or a subclass of the original type.

    Note that if an argument has no specified type, the compiler treats the argument as %StringOpens in a new tab. Thus if an argument in the superclass method has no type, the corresponding argument of a subclass method can be %StringOpens in a new tab, can be a subclass of %StringOpens in a new tab, or can have no type.

  • The method in the subclass should receive argument values in the same way as the method in the superclass. For example, if a given argument is passed by reference in the superclass, the same argument should be passed by reference in the subclass.

    If the method signatures are inconsistent in this regard, it is harder for other developers to know how to use the methods appropriately. Note, however, that the compiler does not issue an error.

If your method implementation needs to call the method of the same name as defined in the superclass, you can use the syntax ##super(), which is discussed in the subsections. This discussion applies to code that is written in ObjectScript.

##super()

Within a method, use the following expression to call the method of the same name as defined in the nearest superclass:

##super()

You can use this expression with the DO command. If the method returns a value, you can use SET, or you can use it as part of another expression. The following shows some variations:

 do ##super()
 set returnvalue=##super()_"additional string"
Note:

##super is not case-sensitive. Also note that, unlike other features in this chapter, ##super() is available within Basic methods as well as within ObjectScript methods.

This is useful if you define a method that should invoke the existing method of the superclass and then perform some additional steps such as modifying its returned value.

##super and Method Arguments

##super also works with methods that accept arguments. If the subclass method does not specify a default value for an argument, make sure that the method passes the argument by reference to the superclass.

For example, suppose the code for the method in the superclass (MyClass.Up.SelfAdd()) is:

ClassMethod SelfAdd(Arg As %Integer)
{
    Write Arg,!
    Write Arg + Arg
}

then its output is:

>Do ##Class(MyClass.Up).SelfAdd(2)
2
4
>

The method in the subclass (MyClass.Down.SelfAdd()) uses ##super and passes the argument by reference:

ClassMethod SelfAdd(Arg1 As %Integer)
{
    Do ##super(.Arg1)
    Write !
    Write Arg1 + Arg1 + Arg1
}

then its output is:

>Do ##Class(MyClass.Down).SelfAdd(2)
2
4
6
>

In MyClass.Down.SelfAdd(), notice the period before the argument name. If we omitted this and we invoked the method without providing an argument, we would receive an <UNDEFINED> error.

Calls That ##super Affects

##super only affects the current method call. If that method makes any other calls, those calls are relative to the current object or class, not the superclass. For example, suppose that MyClass.Up has MyName() and CallMyName() methods:

Class MyClass.Up Extends %Persistent
{

ClassMethod CallMyName()
{
    Do ..MyName()
}

ClassMethod MyName()
{
    Write "Called from MyClass.Up",!
}

}

and that MyClass.Down overrides those methods as follows:

Class MyClass.Down Extends MyClass.Up
{

ClassMethod CallMyName()
{
    Do ##super()
}

ClassMethod MyName()
{
    Write "Called from MyClass.Down",!
}

}

then invoking the CallMyName() methods have the following results:

USER>d ##class(MyClass.Up).CallMyName()
Called from MyClass.Up
 
USER>d ##class(MyClass.Down).CallMyName()
Called from MyClass.Down

MyClass.Down.CallMyName() has different output from MyClass.Up.CallMyName() because its CallMyName() method includes ##super and so calls the MyClass.Up.CallMyName() method, which then calls the uncast MyClass.Down.MyName() method.

Number of Arguments

In some cases, you might find it necessary to add new arguments to a method in a superclass, thus resulting in more arguments than are defined in the method in a subclass. The subclasses will still compile, because (for convenience) the compiler appends the added arguments to the method in the subclass. In most cases, you should still examine all the subclasses that extend the method, and edit the signatures to account for the additional arguments, and decide whether you want to edit the code also. Even if you do not want to edit signatures or code, you still must consider two points:

  • Make sure that the added argument names are not the same as the names of any variables used in the method in the subclass. The compiler appends the added arguments to the method in the subclass. If these arguments happen to have the same names as variables used in the method of the subclass, unintended results will occur.

  • If the method in the subclass uses the added arguments (because this method uses ##super), make sure that the method in the superclass specifies default values for the added arguments.

FeedbackOpens in a new tab