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.
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.
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.
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"); }
}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-FlyableQuick check
Why can a Java class implement multiple interfaces but extend only one class?
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.