Unit 2 · Lesson 516 minAcademic review pending

A promise about behaviour, with no implementation attached

An abstract class says "you are a kind of me." An interface says only "you can do this" — a purer contract that lets unrelated classes share a capability without sharing any ancestry at all.

Choose explanation

After this lesson

You should be able to

  • Define an interface and implement it in an unrelated class.
  • Explain how an interface differs from an abstract class.
  • Explain why a class can implement several interfaces but extend only one class.
01

A capability, not a family tree

A Bird and an Airplane share nothing in common as a family tree — one is a living thing, the other a machine — but both can fly. Forcing them into the same class hierarchy just to share a fly() method would be a false is-a relationship, exactly the mistake the earlier lesson warned against. An interface solves this: it declares a capability, Flyable, with no implementation, that any unrelated class can promise to fulfil.

implements, not extends, is the keyword for this relationship. A class implementing an interface is making a promise: I will provide real code for every method this interface declares, or the compiler will refuse to accept the class as complete.

Two unrelated classes, one shared capability
interface Flyable {
    void fly();          // no body — just a promise
}

class Bird implements Flyable {
    public void fly() { System.out.println("Flapping wings"); }
}

class Airplane implements Flyable {
    public void fly() { System.out.println("Using engines"); }
}
02

One extends, many implements

Java allows a class to extend only one other class — this is deliberate, because multiple inheritance of implementation creates a genuinely hard problem: if two parent classes both provide a conflicting version of the same method, which one should win? Java sidesteps that ambiguity entirely by disallowing it. A class can, however, implement as many interfaces as it needs, because interfaces before Java 8 carried no implementation at all — there was nothing to conflict.

This is the combination form of inheritance from earlier in this unit, made possible without the conflict problem: a class like Duck can implement both Flyable and Swimmable, genuinely combining two independent capabilities, something a single-parent extends relationship could never express cleanly.

Try it yourself

Define a Swimmable interface with a swim() method. Make Duck implement both Flyable (from the code above) and Swimmable. Write a method that accepts a Flyable and calls fly() on it, and show that a Duck object can be passed to it.

Need a hint?

Implementing multiple interfaces is just a comma-separated list after implements — Duck implements Flyable, Swimmable.

Check the worked solution

A Duck is-Flyable and is-Swimmable simultaneously, without either capability knowing the other exists — each interface is a completely independent promise. Passing a Duck to a method expecting Flyable works for the same substitutability reason a Student could be passed where a Person was expected, extended here from class inheritance to interface implementation.

interface Swimmable {
    void swim();
}

class Duck implements Flyable, Swimmable {
    public void fly() { System.out.println("Duck flying"); }
    public void swim() { System.out.println("Duck swimming"); }
}

static void makeItFly(Flyable f) {
    f.fly();
}

// makeItFly(new Duck());   // works — Duck is-Flyable

Quick check

Why can a Java class implement multiple interfaces but extend only one class?

Select an answer to check your thinking.

Why this lesson exists

Syllabus mapping

differences between classes and interfaces, defining an interface, implementing interface, applying interfaces, variables in interface and extending interfaces.

Maps to course outcome CO2.