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:

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.