next up previous
Next: 2.3.2.4 Marker interfaces. Up: 2.3.2 Illustrative Examples Previous: 2.3.2.2 Code reuse and

2.3.2.3 Code reuse, selective overriding, no polymorphism.

Ideally, the well-known Clock applet class ought to multiply inherit from built-in classes java.applet.Applet and
[4] java.lang.Thread. That is,

class Clock extends Applet, Thread { ... };

This declaration, which is illegal in Java, enables the clock to run in a browser, and update itself periodically on a separate thread. To facilitate implementation of such classes by single inheritance, Java defines an interface

interface Runnable { public void run(); }

and a Thread constructor of the form

Thread (Runnable r) { ... }.

Now class Clock can be coded in Java as:

    class Clock extends Applet implements Runnable  {
        Thread t = new Thread (this);         ...
        public void run { ... };              ...

        // connecting methods of Applet and Thread
        public void start() { 
           t.start();             ...
        }
    }
The class Thread exemplifies an implementation of overrriding via stored back-references that are passed to the parent object in its constructor.

This pattern of related interfaces, classes, and constructors enables code reuse and customization. Anticipating the need for customization, vendors can apply it in designing utility classes and frameworks, to facilitate their use in multiple inheritance contexts.

The pattern is appropriate in cases where the ability to customize inherited methods (for example, start()) by overriding one or a few methods on which they rely (for example, run()) is required, but the ability to substitute child instances for parent instances (for example, Applets for Threads) is not relevant or impossible to implement.

But why didn't the designers of Java define a more complex interface than Runnable? It would have created the opportunity for conflicts. For instance, the start() method is defined in both classes -- Applet and Thread -- and with different semantics, while class Clock can support only one definition of start(). As explained in Section [*] such conflicts prohibit using Clocks as Threads. So a larger interface than Runnable would not have been beneficial anyway but would have added the risk of subtle errors.


next up previous
Next: 2.3.2.4 Marker interfaces. Up: 2.3.2 Illustrative Examples Previous: 2.3.2.2 Code reuse and
T. K. Prasad