The Artima Developer Community
Sponsored Link

Designing with Interfaces
One Programmer's Struggle to Understand the Interface
by Bill Venners
First Published in JavaWorld, November 1998

<<  Page 2 of 6  >>

Advertisement

Interfaces and the 'diamond problem'
One justification of interfaces that I had heard early on was that they solved the "diamond problem" of traditional multiple inheritance. The diamond problem is an ambiguity that can occur when a class multiply inherits from two classes that both descend from a common superclass. For example, in Michael Crichton's novel Jurassic Park, scientists combine dinosaur DNA with DNA from modern frogs to get an animal that resembled a dinosaur but in some ways acted like a frog. At the end of the novel, the heros of the story stumble on dinosaur eggs. The dinosaurs, which were all created female to prevent fraternization in the wild, were reproducing. Chrichton attributed this miracle of love to the snippets of frog DNA the scientists had used to fill in missing pieces of the dinosaur DNA. In frog populations dominated by one sex, Chrichton says, some frogs of the dominant sex may spontaneously change their sex. (Although this seems like a good thing for the survival of the frog species, it must be terribly confusing for the individual frogs involved.) The dinosaurs in Jurassic Park had inadvertently inherited this spontaneous sex-change behavior from their frog ancestry, with tragic consequences.

This Jurassic Park scenario potentially could be represented by the following inheritance hierarchy:


Figure 1. Multiple inheritance in Jurassic Park

The diamond problem can arise in inheritance hierarchies like the one shown in Figure 1. In fact, the diamond problem gets its name from the diamond shape of such an inheritance hierarchy. One way the diamond problem can arise in the Jurassic Park hierarchy is if both Dinosaur and Frog, but not Frogosaur, override a method declared in Animal. Here's what the code might look like if Java supported traditional multiple inheritance:

abstract class Animal {

    abstract void talk();
}

class Frog extends Animal {

    void talk() {

        System.out.println("Ribit, ribit.");
}

class Dinosaur extends Animal {

    void talk() {
        System.out.println("Oh I'm a dinosaur and I'm OK...");
    }
}

// (This won't compile, of course, because Java
// only supports single inheritance.)
class Frogosaur extends Frog, Dinosaur {
}

The diamond problem rears its ugly head when someone tries to invoke talk() on a Frogosaur object from an Animal reference, as in:

Animal animal = new Frogosaur();
animal.talk();

Because of the ambiguity caused by the diamond problem, it isn't clear whether the runtime system should invoke Frog's or Dinosaur's implementation of talk(). Will a Frogosaur croak "Ribbit, Ribbit." or sing "Oh, I'm a dinosaur and I'm okay..."?

The diamond problem would also arise if Animal had declared a public instance variable, which Frogosaur would then have inherited from both Dinosaur and Frog. When referring to this variable in a Frogosaur object, which copy of the variable -- Frog's or Dinosaur's -- would be selected? Or, perhaps, would there be only one copy of the variable in a Frogosaur object?

In Java, interfaces solve all these ambiguities caused by the diamond problem. Through interfaces, Java allows multiple inheritance of interface but not of implementation. Implementation, which includes instance variables and method implementations, is always singly inherited. As a result, confusion will never arise in Java over which inherited instance variable or method implementation to use.

<<  Page 2 of 6  >>


Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us