Statement FINAL | INTRODUCE | OVERRIDE Foundation
Control overriding and hiding of method in subclasses or superclasses
[FINAL | INTRODUCE | OVERRIDE] [CLASS] METHOD <MethodName>
By default all methods in Xbase++ are virtual override. This leads to the effect that a method implemented by derived classes overrides the implementation of its superclass. To control overriding and hiding of methods in your class design the attributes FINAL, INTRODUCE and OVERRIDE can be used. The following code illustrates the default behavior of Xbase++, executing the method :Bark() on a object of class A() prints "(A) says:...", while executing the method :Bark() on a object of class B() prints "(B) says:...".
CLASS A
EXPORTED:
INLINE METHOD Print(cText)
? "(A) says:",cText
RETURN
INLINE METHOD Bark()
::Print( "(A) is barking" )
RETURN
ENDCLASS
CLASS B FROM A
EXPORTED:
INLINE METHOD Print(cText)
? "(B) says:",cText
RETURN
ENDCLASS
Using FINAL ensures that subclasses do not override method implementations of superclasses by simply adding a method with the same name to a subclass. By adding the FINAL modifier to the Print() method declaration at class A(), the execution of the method :Bark() on a object of class B() still prints "(A) says:...". This shows the FINAL declared method Print() from class A() has been executed and not the Print() method from class B()
With INTRODUCE a new method implementation does not override method implementations of its superclasses. By adding INTRODUCE as an attribute to the Print() method at class B(), the execution of Method Bark() on objects of class B() executes method Print() at class A().
Adding OVERRIDE to a method declaration, override behaviour is enforced, even if methods at superclasses are explicitly attributed as FINAL. Assuming the method Print() at class A() is attribute as FINAL, executing method Bark() on objects of class B() leads to the execution of the Print() method at class A(). Adding OVERRIDE as an explicit attribute to the method declaration of Print() at B() leads to the execution of this new method Print() at class B() when executing the method Bark() on objects of class B().
// A class for managing part lists is programmed in this example.
// The FINAL methods make sure that the calculation of total cost
// and average cost is always done in the same way.
CLASS PartList
PROTECTED:
VAR aParts, aPrice
EXPORTED:
METHOD init, add
FINAL METHOD totalCost, averageCost
ENDCLASS
METHOD PartList:init
::aParts := {}
::aPrice := {}
RETURN self
METHOD PartList:add( cPart, nPrice )
AAdd( ::aParts, cPart )
AAdd( ::aPrice, nPrice )
RETURN self
// Calculation of total costs
METHOD PartList:totalCost
LOCAL nCost := 0
AEval( ::aPrice, {|n| nCost += n } )
RETURN nCost
// Calculation of average costs
METHOD PartList:averageCost
LOCAL nCost := ::totalCost()
IF ! Empty( ::aParts )
nCost /= Len( ::aParts )
ENDIF
RETURN nCost
If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.