staff@cadlab.sublink.ORG (Alex Martelli) (08/08/90)
>In general, multiple inheritance is almost never needed. I have never >seen a published example of a C++ program using multiple inheritance >that couldn't be coded just as easily using components instead. (This This is a major thesis of T. Cargill, and he's been propounding it at Usenix and UKUUG; indeed, he has rewritten all published examples of multiple inheritance in C++, with single inheritance or none at all, and they're better (see the proceedings of the above conferences). >is not true for some other systems, such as flavors.) Sometimes multiple >inheritance is the best way to think of a problem, but it is grossly misused I wonder! Yourdon and Coad, in "Object-Oriented Analysis", claim that M.I. is no doubt great as a CODING technique, e.g. for C++ 2.0, but for ANALYSIS ("best way to think of a problem"), they shun it as leading to unwarranted complication in "modeling the problem space". If the analysis theoreticians want MI only in coding, and the coding freaks want to leave MI for analysis, what does this suggest...? >in the C++ world. I would be happy for people to point me to examples of >multiple inheritance in which it is obviously better than any of the >design alternatives. The best cathegory of examples I have seen in books/articles/talks by Bertrand Meyers, and it has to do with parametric classes with some constraints on operations which need to be available on the formal types which are the parameters. Instead of ad-hoc, weakish expression of the constraints like in Ada, one can say, for example: "generic class AVL_TREE of T:COMPARABLE" to express the fact that the T parameter of AVL_TREE must inherit from COMPARABLE, which presumably one has already coded as an abstract class specifying the comparison operator (including some of its semantic constraints, in assertions); now in the code for AVL_TREE I can invoke the comparison operator on objects of formal type T. With MI, this does not really limit what can be put on an AVL_TREE! Suppose I have a class WORKSTATION, which of course has NOT inherited from COMPARABLE, but does have a SERIAL_NUMBER attribute; I can make a COMPARABLE_WORKSTATION with MI from WORKSTATION and COMPARABLE, by implementing the comparison as being done on the serial numbers, and have an AVL_TREE of them for inventory, look-up, etc. Of course I *could* do the same by just inheriting from COMPARABLE and HAVING a field of type WORKSTATION, rather than BEING a workstation; in general, the IS-A and HAVE-A relations are not as disjoint as one would think in the first place! However, I would then have some trouble applying other WORKSTATION ops & data structures to them. I have obviously not yet thought enough about these topics, but it seems to me they're deeply connected with the dual nature of class inheritance - inheritance of SPECIFICATIONS for an interface, and of IMPLEMENTATION... I would welcome a discussion on this, and of MI in general. Also think of the practical concerns - maybe there are cases where MI would not be needed IF one could redesign each and every class hierarchy from scratch, but MI makes it easier to reuse specs and code, maybe from vendor-bought hierarchies, WITHOUT redesign...? -- Alex Martelli - CAD.LAB s.p.a., v. Stalingrado 45, Bologna, Italia Email: (work:) staff@cadlab.sublink.org, (home:) alex@am.sublink.org Phone: (work:) ++39 (51) 371099, (home:) ++39 (51) 250434; Fax: ++39 (51) 366964 (work only; any time of day or night).