Previous Table of Contents Next


9.9.10. Joining and Uneffecting

It is not an error to inherit two deferred features from different parents under the same name, provided they have the same signature (number and types of arguments and result). In that case, a feature join takes place: The features are merged into just one—with their preconditions and postconditions, if any, respectively or-ed and and-ed.

More generally, it is permitted to have any number of deferred features and one effective feature that share the same name: The effective version applies to all the others.

All this is not a violation of the final name rule (section 9.9.8) because the name clashes prohibited by the rule involve two different features having the same final name; here the result is just one feature, resulting from the join of all the inherited versions.

Sometimes we may want to join effective features inherited from different parents, assuming again the features have compatible signatures. One way is to redefine them all into a new version; then they again become one feature, with no name clash in the sense of the final name rule. In other cases, we may simply want one of the inherited implementations to take over the others. The solution is to revert to the preceding case by uneffecting the other features; uneffecting an inherited effective feature makes it deferred (this is the reverse of effecting, which turns an inherited deferred feature into an effective one). The syntax uses the undefine subclause:

   class D inherit
       A
           rename
               g as f         -- g was effective in A
           undefine
               f
           end
       B
           undefine f end      -- f was effective in B
       C
            -- C also has an effective f, which will serve as
                implementation
            -- for the result of the join.
   feature
       ...

Again what counts, to determine if there is an invalid name clash, is the final name of the features. In this example, two of the joined features were originally called f; the one from A was called g, but in D, it is renamed as f, so without the undefinition it would cause an invalid name clash.

Feature joining is the most common application of uneffecting. In some non-joining cases, however, it may be useful to forget the original implementation of a feature and let it start a new life devoid of any burden from the past.

9.9.11. Changing the Export Status

Another feature adaptation subclause makes it possible to change the export status of an inherited feature. By default—covering the behavior desired in the vast majority of practical cases—an inherited feature keeps its original export status (exported, secret, or selectively exported). In some cases, however, this is not appropriate:

  A feature may have played a purely implementation-oriented role in the parent but become interesting to clients of the heir. Its status changes from secret to exported.
  In implementation inheritance (for example, ARRAYED_LIST inheriting from ARRAY), an exported feature of the parent may not be suitable for direct use by clients of the heir. The change of status in this case is the reverse of the previous one.
You can achieve either of these goals by writing
   class D inherit
       A
           export {X, Y, ...} feature1, feature2, ... end
       ...

This gives a new export status to the features listed (under their final names because, as noted, export, like all other subclauses, comes after rename if present): They become exported to the classes listed. In most cases, this list of classes (X, Y, and so on) consists of just ANY, to re-export a previously secret feature, or NONE, to hide a previously exported feature. It is also possible, in lieu of the feature list, to use the keyword all to apply the new status to all features inherited from the listed parent. Then there can be more than one class-feature list, as in

   class ARRAYED_LIST [G] inherit
       ARRAY [G]
           rename
               count as capacity, item as array_item, put as array_put
           export
               {NONE} all
               {ANY} capacity
           end
       ...

where any explicit listing of a feature, such as capacity, takes precedence over the export status specified for all. Here most features of ARRAY are secret in ARRAYED_LIST because the clients should not be permitted to manipulate array entries directly. They manipulate them indirectly through list features such as extend and item, whose implementation relies on array_item and array_put, but ARRAY’s feature count remains useful, under the name capacity, to the clients of ARRAYED_LIST.


Previous Table of Contents Next