Inheritance works well when. . .
Inheritance is inappropriate when. . .
If in doubt. . . Don't inherit! Or. . . Reorganize class hierarchy so that inheritance makes sense.
Forwarding allows an operation invoked on object A to be forwarded to component object B.
Inheritance is similar except that the original object is remembered, so that "send to self" works.
It is sometimes useful to inherit from more than one class. A subclass inherits all methods and instance variables of superclasses.
For example. . .
Most languages allow multiple inheritance (e.g., C++, CLOS).
What if methods or instance variables of the same name are inherited from different superclasses?
For example. . .
There are a number of approaches to solving this problem.
CLOS (Common Lisp Object System) resolves method name ambiguities by selecting methods in the order in which they appear in the subclass definition. For example. . .
(defclass Square (Rectangle Rhombus) (. . .))
Instance variables with the same name are combined.
C++ reports a compile-time error when an ambiguity is detected. A programmer can override the ambiguous method in the subclass and explicitly indicate what method to use.
Don't allow multiple inheritance!
Suppose two superclasses have a common ancestor class. This seems like a common thing that we should handle properly.
(defclass Parallelogram (. . .) (. . .))
(defclass Rectangle (Parallelogram) (. . .))
(defclass Rhombus (Parallelogram) (. . .))
(defclass Square (Rectangle Rhombus) (. . .))
No problem, CLOS is searching ordered class hierarchy.
In C++, the compiler recognizes and allows this special case, and does not duplicate instance vars and methods.
We have looked at receiver-oriented single dispatching so far. In this case, the method to be invoked is selected from the class (or superclass) of the receiver object. The problem with this approach is that certain situations are very strange. E.g., binary operations.
Multi-methods allow a programmer to specialize on more than one argument. CLOS and Cecil have multi-methods.
Multi-methods are not in a single class.
(defmethod display ((r Rectangle) (d Device)) (. . .))
(defmethod display ((r Rectangle) (d XWindow)) (. . .))
(defmethod display ((r Rectangle) (d Postscript)) (. . .))
(defmethod display ((c Circle) (d Device)) (. . .))
(defmethod display ((x Circle) (d MacDisplay)) (. . .))
. . .
How does the run-time system decide which method to select?
In CLOS, methods are ordered by their specificity as follows.
This is a little weird, because specificity depends on the order of the arguments. Some languages consider arguments uniformly.
(defmethod equal? ((v1 Float) (v2 Float)) (. . .))
(defmethod equal? ((v1 Float) (v2 Int)) (. . .))
(defmethod equal? ((v1 Int) (v2 Float)) (. . .))
(defmethod equal? ((v1 Int) (v2 Int)) (. . .))
Very useful for binary methods.
Unify and generalize. . .