How-to: Property extension
The classic approach for implementing polymorphism can look as follows:
Let's create an abstract class Shape
with an abstract property square
:
CLASS ABSTRACT Shape;
square 'Area' = ABSTRACT DOUBLE (Shape);
Now, let's create classes Rectangle
and Circle
inherited from Shape
:
CLASS Rectangle : Shape;
width 'Width' = DATA DOUBLE (Rectangle);
height 'Height' = DATA DOUBLE (Rectangle);
CLASS Circle : Shape;
radius 'Circle radius' = DATA DOUBLE (Circle);
Define the implementation of the abstract property square
for the created classes:
square(rectangle) += width(rectangle) * height(rectangle);
square(circle) += radius(circle) * radius(circle) * 3.14;
Let's assume that we need to make it so that in certain cases we can override the method of calculating the area for the Circle
class. In this case, we can use an abstract property, whose implementation can be changed in a different module, to add a kind of "entry point" to the line defining the implementation of area for a circle :
overSquareCircle 'Overridden area' = ABSTRACT DOUBLE (Circle);
square(circle) += OVERRIDE overSquareCircle(circle), (radius(circle) * radius(circle) * 3.14);
If the overSquareCircle
property is not implemented in any module, its value will always be NULL
and the base area calculation mechanism will be used. To change the calculation method to be used, you can define a different implementation in a certain MyShape
module.
MODULE MyShape;
REQUIRE Shape;
// using a formula with higher accuracy
overSquareCircle (circle) += radius(circle) * radius(circle) * 3.14159265359;
Note that you can use any other expressions instead of the OVERRIDE
operator. In particular, (+)
and (-)
operators may be the most frequently used.