Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!emory!gatech!bloom-beacon!eru!hagbard!sunic!mcsun!ukc!dcl-cs!aber-cs!athene!pcg From: pcg@cs.aber.ac.uk (Piercarlo Grandi) Newsgroups: comp.object Subject: Re: Examples of Multiple Inheritance? Message-ID: Date: 6 Dec 90 16:04:40 GMT References: <60700005@inmet> Sender: pcg@aber-cs.UUCP Organization: Coleg Prifysgol Cymru Lines: 88 Nntp-Posting-Host: odin In-reply-to: stt@inmet.inmet.com's message of 3 Dec 90 20:05:00 GMT On 3 Dec 90 20:05:00 GMT, stt@inmet.inmet.com said: stt> We are looking for a few good examples of multiple inheritance stt> in the programming language (especially C++) arena (as opposed to OODB, stt> OOD, OOA arenas) The small book on CLOS, "Object Oriented programming in CL" has I think fairly good ideas and examples about MI. Because they treat it as an algebra of mixing and matching interfaces. Also look at Trellis, and Emerald. Recent issues of OOPSLA and POPL proceedings also have interesting discussions on mixing and matching interfaces, implementations and specifications in a less constrained way than MI. stt> We are looking for an example of a C++ class (or Eiffel, Objective C, stt> etc.) which is a "true" sub-class of two (or more) parent classes; stt> that is, it bears the "is-a" relationship to multiple parents. Haha. So you haven't read my all important, wonderful and revolutionary thoughts on the matter :-). So you don't say which is-a relationship you mean; is-a as interface, as implementation, or as specification? MI in traditional OO languages implements composition of interfaces mainly, and subsidiarily composition of implementations (or viceversa depending on the style of language). Normally (with some exception in Eiffel and a few others) it deals not with composition of semantics. If you read Lippman's book on C++ you get the impression that MI is about (hierarchical) data design (in the database sense). Uhmmmm. I tend to be skeptical :-). Data design is a more serious issue than MI. To confuse data design with reuse seems to be fairly strange. stt> Our hypothesis is that multiple inheritance can rarely be useful stt> unless planned for in advance, which seems to defeat the purpose. stt> If it does require advance planning, then we anticipate that those stt> situations would be amenable to other structures, perhaps, for example, stt> a component with a pointer to its enclosing object. The latter is known as "delegation" if brought to its logical conclusion. Note that inheritance as we commonly know it is actually nothing else than a syntactic device by which fields of fields of a record can be named as if they were fields of that record (e.g. assuming that it is unambiguous, derived.base.field can be abbreviated as derived.field), i.e. union of interfaces. The really interesting bits are overloading and genericity, either static or dynamic. These are good problems even if you don't have "inheritance". These are problems about static or runtime matching of functions with types. They exist and demand a solution even in non OO languages; consider X windows for example. What we need is a nice notation to express the same things that we already do clumsily in Lisp, or C, or Ada (even if it does not have functions as first class objects, and thus no runtime genericity, unless you use access types to tasks). We also need that the notation be a bit supported by the environment, and without crazy limitations (consider the difficulty one has in Ada to provide and let the user choose different bodies for the same package spec, and the _impossibility_ to do viceversa). stt> Multiple inheritance seems to add significant overhead to an OOPL stt> even when not being used in a system, This is *not* true. What adds overhead is dynamic overloading and dynamic genericity (the static varieties are nearly cost free). They are just a bit more expensive under multiple than single inheritance simply because the prefixing trick (which puts base objects at offset zero in the derived one) is not in general possible, so one has to deal with non zero offsets either at compile time (if no virtual bases are involved) or runtime (if virtual bases are involved). stt> so we are looking for convincing examples that it's benefits stt> outweigh the cost. Note that multiple (interface,implementation,specification) composition is a need, and so are dynamic/static overloading/genericity. You can only choose whether to put them in the language as primitives, or to let the programmer simulate them (just like non nested control and environment structures). I think that even if they are rarely used (but they are not! Simply people do not know they are simulating them!) they had better be in the language, because otherwise one needs to do contortions (like using access types to tasks instead of to procedures in Ada...). -- Piercarlo Grandi | ARPA: pcg%uk.ac.aber.cs@nsfnet-relay.ac.uk Dept of CS, UCW Aberystwyth | UUCP: ...!mcsun!ukc!aber-cs!pcg Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk Brought to you by Super Global Mega Corp .com