Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!bu.edu!inmet!stt From: stt@inmet.inmet.com Newsgroups: comp.object Subject: Re: Examples of Multiple Inheritance? Message-ID: <60700007@inmet> Date: 11 Dec 90 23:33:00 GMT References: <60700005@inmet> Lines: 143 Nf-ID: #R:inmet:60700005:inmet:60700007:000:4855 Nf-From: inmet.inmet.com!stt Dec 11 18:33:00 1990 Re: Examples of Multiple Inheritance? Here are my proposals for handling Multiple Inheritance in programming languages: There seem to be two relatively distinct ways in which MI is used: as a mix-in to a known base class, and as a combination of otherwise unrelated classes. It would seem that if these two uses were clearly distinguished, then the resulting model might actually be easier to understand and implement efficiently. Note that C++ makes effectively this distinction via the concept of "virtual" base classes, but I find their terminology confusing, and they don't seem to get any major implementation or conceptual simplification from this distinction. MIX-INS When structuring a system with mix-ins, a base class tends to be partitioned into independent "aspects" (inventing terminology here), and a given mix-in is "responsible" for a particular aspect of the behavior of the class. For now, let us name these mix-ins as follows: .. A given subclass of the base class must select the appropriate mix-in for each aspect, or accept by default the behavior selected by its immediate superclass. A given mix-in should not presume that some other specific mix-in has been chosen, but it may assume that, for each aspect of behavior, a mix-in has been chosen to handle it. This guarantees independence of implementation of mix-ins, while they may all depend on the interface of the base class. COMBOS When building up a class by combining unrelated parent classes, the goal is to have a single object which can "pretend" it is an instance of any of the parent classes. Furthermore, in overriding the behavior of one of the parent classes, the implementation of a method for the combo class may take advantage of the presence of methods defined on the other parents. Apparently, each parent is handling a different "aspect" of the behavior of the combo class. For now, let us name each parent of a class as: .. MIX-IN COMBOS? If you compare mix-ins with combos, there is a striking duality. Combos are effectively creating a "mix-in" situation after the fact. Two parents of a combo could be considered the default (mix-in) implementations of two aspects of the behavior of the combo. Given a combo, it would seem to make sense to extend it using the mix-in approach, now overriding the default implementation of each aspect, originally inherited from a parent, with implementations which may "know" they are mix-ins to the (base) combo-class. PARTITIONED INTERFACE In both of the above approaches, it seems that it is natural to partition the overall interface of a class into multiple "aspects." Aspects then become the unit for replacement on a mix-in basis. The interface to an "aspect" should be independent of the interface to any other aspect. The implementation of an aspect specifies its assumptions, by identifying which base-class it is based on, which indirectly indicates what other aspects are supported. Alternatively, the implementation of an aspect (i.e. a mix-in) could directly identify which other aspects it depends on, and any base class which includes implementations for those aspects may select that mix-in. ASPECTS = MODULES? If we treat aspects as modules, then we see a clear resemblance between the module concept of Modula-2 or the package concept of Ada, and aspects, with the "import" clause or the "with" clause indicating the inter-aspect dependence. However, it is still useful to have higher level encapsulation constructs like modules or packages, in which sets of related classes are declared. STRAWMAN Here is a strawman proposal which incorporates the above thinking: -- Define an aspect for use in a class aspect Fum is {visible attribute/component} {visible operation} end Fum; -- Define another aspect for use in a class aspect Foo is {visible attribute/component} {visible operation} end Foo; -- Define an implementation of the Fum aspect with Foo; -- Require aspect Foo to be present in class aspect body Fum.Foozle is -- Code within here may call operations defined for Foo aspect {private attribute/component} {body for private operation} {body for visible operation} end Fum.Foozle; aspect body Foo.Frazzle is -- Implementation of Foo operations . . . end Foo.Frazzle; -- Define a class which has various aspects class Combo_Mix_In combines Foo.Frazzle, Fum.Foozle; . . . -- Define an instance of the class X : Combo_Mix_In; -- Now we can say things like: X.Fum.(...); X.Foo. := 5; ========================== Any takers? More ideas later... (I hope!) S. Tucker Taft stt@inmet.inmet.com ...!uunet!inmet!stt Intermetrics, Inc. 733 Concord Avenue Cambridge, MA 02138