Multiple Inheritance Through Interfaces
A smartphone is a phone, a camera and a music player at the same time. A Java class can extend only one class, but it can implement as many interfaces as it needs. That's how Java offers multiple inheritance of type: one object can be used wherever any of its interfaces is expected, without the diamond problem that multiple class inheritance would bring.
One Class, Several Interfaces
public class Gadgets {
interface Phone { String call(String who); }
interface Camera { String click(); }
interface MusicPlayer { String play(String song); }
static class Smartphone implements Phone, Camera, MusicPlayer {
public String call(String who) { return "Calling " + who; }
public String click() { return "Photo saved"; }
public String play(String song) { return "Playing " + song; }
}
static void ring(Phone p) { System.out.println(p.call("Srihitha")); }
static void shoot(Camera c) { System.out.println(c.click()); }
public static void main(String[] args) {
Smartphone mine = new Smartphone();
ring(mine);
shoot(mine);
MusicPlayer player = mine;
System.out.println(player.play("Navika's playlist"));
System.out.println(mine instanceof Camera);
}
}Calling Srihitha
Photo saved
Playing Navika's playlist
trueHow it works
Smartphone implements Phone, Camera, MusicPlayer: one class signs three contracts, separated by commas.- The same object is passed to
ringas aPhoneand toshootas aCamera. Each method sees only the part of the object it needs. mine instanceof Cameraistrue: the object is aCamera, as well as aPhoneand aMusicPlayer.
Try it yourself: add an interface Torch with String lightOn() and make Smartphone implement it too.
Interfaces Extending Interfaces
An interface can extend several interfaces at once, combining their contracts:
public class Combined {
interface Readable { String read(); }
interface Writable { void write(String text); }
interface Notebook extends Readable, Writable { int pages(); }
static class SchoolNotebook implements Notebook {
private final StringBuilder text = new StringBuilder();
public String read() { return text.toString(); }
public void write(String t) { text.append(t); }
public int pages() { return 100; }
}
public static void main(String[] args) {
Notebook book = new SchoolNotebook();
book.write("Advitha's science notes");
System.out.println(book.read() + ", " + book.pages() + " pages");
}
}Advitha's science notes, 100 pagesNotebook extends Readable and Writable, so a class implementing Notebook must provide all three methods.
| Declaration | How many parents |
|---|---|
class A extends B | One class |
class A implements X, Y | Any number of interfaces |
class A extends B implements X, Y | One class plus any number of interfaces |
interface X extends Y, Z | Any number of interfaces (interfaces never implement) |
Why No Diamond Problem
Interfaces carry no instance fields, so a class can never end up with two copies of the same state. Abstract methods with the same signature from two interfaces simply merge: the class implements the method once and satisfies both. Only default methods with code can clash, and Java then refuses to compile until the class decides (see "Diamond Problem with Default Methods").
Common Mistakes
Writing implements before extends. The order is fixed: class C extends B implements X.
Using implements between interfaces. An interface extends other interfaces.
Building one giant interface. Classes then have to implement methods they don't need.
Interview Corner
Does Java support multiple inheritance?
Not of classes: a class has exactly one superclass. It supports multiple inheritance of type through interfaces: a class can implement many interfaces and an interface can extend many interfaces. Since Java 8, default methods also allow inheriting behavior from several interfaces, with compile-time rules that force the class to resolve any conflict.
What happens if two interfaces declare the same abstract method?
Nothing problematic. The implementing class provides one method with that signature, and it satisfies both interfaces. A conflict arises only if both supply default implementations, or if the return types are incompatible.
Practice
- Easy: Create interfaces
SwimmerandRunnerand a classTriathletethat implements both. Pass the same object to a method that takes aSwimmerand another that takes aRunner. - Harder: Create
interface Account extends Depositable, Withdrawableand aSavingsAccountthat implements it. Show that aSavingsAccountcan be passed where any of the three types is expected.
Key Takeaways
Was this tutorial helpful?