craig@Neon.Stanford.EDU (Craig D. Chambers) (11/18/90)
In article <1990Nov16.065609.15460@tukki.jyu.fi> sakkinen@jytko.jyu.fi (Markku Sakkinen) writes: >In article <11113@pt.cs.cmu.edu> ddean@rain.andrew.cmu.edu (Drew Dean) writes: >> if a subclass only inherits parts of its superclass >>(ie. some subset of the methods and/or variables), how can an instance >>of the subclass be used anywhere an instance of the superclass can be used ? >>In my (comparably primitive) understanding of OOP, this is important. Without >>this property, what good are abstract classes, which seem to be a useful >>organizational tool ? > >Such partial inheritance can only be used for inheriting implementation >(what I called "incidental inheritance" in my ECOOP'89 paper), >thus more typically with concrete than abstract superclasses. >An instance of the subclass can _not_ be substituted for an instance >of the superclass. > >In my opinion, inheriting only parts of superclass, say C, >into a subclass, say D, is a highly dubious idea even for this purpose. If these comments are in response to my earlier posting, then I believe I have been misunderstood. I'm not suggesting that programmers combine random pieces of source code to form new classes, constantly patching code with partial inheritance to fix bugs or add functionality. Nooooo. Nor am I talking about systems where source code is unavailable and so class hierarchies must be bent out of shape. While this may be a problem for commercial software frameworks, source code is always available in my ivory tower. When I talk about inheriting parts of classes, I am referring to the different aspects or facets (I don't have a better word yet) of classes. These aspects were listed in my previous posting, but since people didn't seem to read them there, I'll (briefly) repeat: Aspect 1: Source code of methods Aspect 2: Format of instances (instance variables/instance template) Aspect 3: Specification of type/interface Most existing class-based languages combine 1 and 2; some combine 3 as well. An classless language uses separate objects for 1 and 2, thus allowing more reuse of code (i.e. inheriting 1) without being forced to inherit representation as well (i.e. overriding 2). As long as a subclass inherits 3 (either explicitly in a statically-typed language with proper subtyping rules or conceptually in a dynamically-typed language), instances of the subclass may be substituted for instances of the superclass, even if 1 and/or 2 are not inherited. Note that to inherit 1 but not 2, a subclass must provide an alternate implementation for any instance variables accessed by methods inherited from the superclass and not overridden. These alternate implementations may be methods instead of variables. The language must access instance variables using messages instead of hard-coded memory loads; Trellis/Owl and Self are languages that do access all variables using messages. Trellis/Owl doesn't explicitly provide for inheriting behavior without representation, but does allow representation to be overridden with behavior, which is just as good. Of course, through disciplined programming conventions you can separate 1 and 2 by using different classes for each. Fairly common wisdom that achieves this is to only inherit from abstract classes, not concrete classes, and only declare instance variables in concrete classes. Abstract classes must access instance variables using messages. Intermediate positions are also possible that only follow this rule when necessary (assuming all source code is available to support future reorganization when necessary). But these conventions are awkward and sacrifice the ability to inherit Aspect 2. Why not just get the inheritance mechanism right in the first place? Or why not just move to a classless language, since they are more flexible and probably more powerful than class-based languages? In the convention above for programming in a non-ideal class-based language, abstract classes are a lot like traits objects in classless languages, and concrete classes are a lot like prototype objects, but prototype objects can inherit Aspect 2 from other prototype objects using the normal object inheritance rules. -- Craig Chambers