next up previous contents
Next: Metalevel Methods Up: Metalevels Previous: Reification of Path References

Delegation and Inheritance as Metalevel Inference

We insisted on section 2.2.2 in double-quoting the fact that refinement ``copied'' the features of a constituent description into the new description--and we also said it was not to be understood as inheritance. We are now in a position to integrate inheritance and delegation--the two main approaches to sharing of object-orientation. Both delegation and inheritance (including multiple inheritance) can be declaratively specified in Noos as different forms of metalevel inference. Furthermore, other variants similar to inheritance can also be specified.

In fact, the refinement operation in Noos can be seen as equivalent to single-inheritance with overriding. Moreover, multiple inheritance be achieved by refinement plus the explicit use of metalevel descriptions.

A simple way to have specialized inheritance is creating a metalevel such that for each feature indicates which methods (defined elsewhere) are to be used. In the following example the methods to be used in person are defined to be those defined in metalevels of citizen and homo-sapiens.

  frag743

In the example above we show that we can explicitly determine which features ``inherit'' (reuse) methods of citizen and which of homo-sapiens, although only two features are shown. Notice also that the description of citizen does not explicitly define a metalevel. However, since metalevel of person has the reference (>> speakes-language of (meta of citizen)), Noos creates the corresponding metalevel, lifts the path reference (>> language national-of) to the metalevel and finally the language feature of the metalevel of person is able to reuse that lifted method.

In order to justify our approach, we need now enter a brief excursus regarding inheritance in OOPLs (object-oriented programming languages). Using multiple inheritance is somewhat tricky in that we have to keep in mind for an object inheriting a method which of several definitions situated in different objects will effectively be reused. The single inheritance scheme avoids this error-prone complication sacrificing flexibility. Multiple inheritance is ``conflictive'': in general an object can inherit (reuse) a method from more that one ancestor. These ``conflicts'' are solved imposing an ordering in the search performed by the inheritance algorithm among ancestors. Since only the first encountered method will be inherited, the others are occluded (overridden) by the ordering--unfortunately different OOPL use different orderings. A problem arises when we have to design a program when we want to reuse methods from an object some of which are occluded and some are not by another object ``more near'' in the inheritance ordering. This can be solved with ``mix-ins'' or even with metaobject protocols that allow programming specialized orderings.

The approach taken by Noos allows a programmer to avoid this conflicts--admittedly in a more verbose way--as shown in the example above: defining a metalevel that explicitly declares for each slot which method or value intends to reuse. We can then have any number of objects reusing this combination of methods simply by refinement--in the example, simply refining person. See moregif at Chapter 4.

Delegation is a form of inference stating that for an object X, some of its feature values are the result of performing the same inference over another object Y--and we say X delegates some tasks to Y. The difference between delegation and inheritance is the following: in inheritance X reuses the method of Y (replacing the self variable now with X) while delegation reuses the value of that method bound to Y. An example of delegation is when the made-of feature of a physical object is delegated to its components: the value is the result of finding the made-of those components. This can be achieved simply by the following description.

frag766

The example shows that my-table is made of crystal and iron by specifying the made-of feature value to be (>> made-of components). Notice however that the fact that made-of is delegated to another object with the same feature name (made-of) is inessential. In Noos, the user can specify a ``delegation'' that does not require the to have the same name. In fact, this was done in the prior example where the metalevel delegates language of person to speaks-language of citizen. Because of this, notice that the way we defined previously multiple inheritance in Noos can be described as metalevel delegation.

If we favor the more strict view that delegation respects the equality of the names involved we can program delegation in Noos as a method--as shown below. Notice that this powerful and simple solution is possible only because (1) methods themselves are first-class objects (values) in Noos, and (2) path references can be reified as methods.

  frag782

The reflective constructs task-name and current-task are bound to the run-time binding of a method and return the name of the feature in which the method is being applied. Once the name of the feature is known delegation simply establishes the reference to the object specified to be delegate-to. A more powerful use of delegation is with default metalevels (cf. below § 2.4.4).


next up previous contents
Next: Metalevel Methods Up: Metalevels Previous: Reification of Path References

Enric Plaza
Thu Jan 23 11:36:28 MET 1997