The properties extension technique allows the developer to declare an abstract action in one module and define its implementation in other modules. This technique is essentially a "postponed definition" of a selection operator, where the operator’s title is defined when the property is declared, and as new functionality (of classes or static objects) is added, selection options are added to the system. Furthermore, variants of selection (if it is not mutually exclusive) can be added both to the beginning and to the end of the abstract property created.
For abstract properties, the expected classes of parameters must be specified. Then the platform will automatically check that the implementations added match these classes. Also, if necessary, you can check that for all descendants of the parameter classes at least one implementation is specified (or exactly one, if the conditions are mutually exclusive).
Extension of properties allows you to:
- Implement the concept of property polymorphism by analogy with certain object-oriented programming languages.
- Remove dependency between modules by adding specific "entry points" to change the way properties are calculated.
Just as for a selection operator, for an abstract property there is a polymorphic form where the selection condition and the result corresponding to it are set by a single property. Accordingly, as in a selection operator, either belonging to the signature of this property or the property itself can be a condition.
Mutual exclusion of conditions
As for a selection operator, you can specify that all conditions of an abstract property must be mutually exclusive. If this option is set, and the conditions are not in fact mutually exclusive, the platform will throw the corresponding error.
It is worth noting that this check is no more than a hint to the platform (for better optimization), and also a kind of self-checking on the part of the developer. However, in many cases it allows you to make the code more transparent and readable (especially given a polymorphic form of the abstract property).
// ABSTRACT MULTI EXCLUSIVE is created
rateChargeExchange(invoice) = ABSTRACT NUMERIC[14,6] (Invoice);
// ABSTRACT CASE OVERRIDE LAST is created, and if there are several suitable implementations,
// the first of them will be calculated
backgroundSku 'Color' (d) = ABSTRACT CASE FULL COLOR (InvoiceDetail);
// The last matching implementation will be calculated here
overVAT = ABSTRACT VALUE OVERRIDE FIRST Range (InvoiceDetail);
CLASS ABSTRACT AClass;
CLASS BClass : AClass;
CLASS CClass : AClass;
CLASS DClass : AClass;
name(AClass a) = ABSTRACT BPSTRING (AClass);
innerName(BClass b) = DATA BPSTRING (BClass);
innerName(CClass c) = DATA BPSTRING (CClass);
innerName(DClass d) = DATA BPSTRING (DClass);
name(BClass b) = 'B' + innerName(b);
name(CClass c) = 'C' + innerName(c);
name[AClass](BClass b) += name(b);
// Here name[AClass] will be found on the left, because the search goes only among abstract properties,
// and on the right name[CClass] will be found
name(CClass c) += name(c);
name(DClass d) += 'DClass' + innerName(d) IF d IS DClass;