More on Object-Oriented Programming


Summary: This document contains my notes for the second object-oriented lecture in CSE341. These notes are derived from Craig Chambers' lecture notes on object-oriented programming.

More on Inheritance

Inheritance works well when. . .

Inheritance is inappropriate when. . .

If in doubt. . . Don't inherit! Or. . . Reorganize class hierarchy so that inheritance makes sense.

Inheritance versus Forwarding

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.

Multiple Inheritance

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).

Multiple Inheritance Deficit: Ambiguity

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 Solution

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++ Solution

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.

Smalltalk/Java Solution

Don't allow multiple inheritance!

Special Case: Diamond-Shaped Inheritance Graphs

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) (. . .))

In CLOS

No problem, CLOS is searching ordered class hierarchy.

In C++

In C++, the compiler recognizes and allows this special case, and does not duplicate instance vars and methods.


Multi-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.

Multi-Method Example

    (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)) (. . .))
    . . .

Overriding Rules

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)) (. . .))

Multi-Method Benefits

Very useful for binary methods.

Unify and generalize. . .

Multi-Method Deficits


echris@cs.washington.edu (5 December 1996)