Interfaces
An interface is a pure contract: it defines what a class must be able to do, without saying
how. Every method in an interface is implicitly public abstract unless it's marked
default or static, and an interface can't hold instance fields — only constants.
Declaring and Implementing an Interface
You declare an interface with the interface keyword, and a class agrees to the contract using
implements. Unlike class inheritance, where a class can only extends one superclass, a
class can implements multiple interfaces at once — this is Java's workaround for not
supporting multiple inheritance of classes.
Example: A Playable Contract
interface Playable {
void play();
}
class MusicTrack implements Playable {
private String title;
MusicTrack(String title) {
this.title = title;
}
@Override
public void play() {
System.out.println("Playing track: " + title);
}
}
class VideoClip implements Playable {
private String fileName;
VideoClip(String fileName) {
this.fileName = fileName;
}
@Override
public void play() {
System.out.println("Playing video: " + fileName);
}
}
What's happening:
MusicTrackandVideoCliphave nothing to do with each other — they don't share a superclass — but both can be treated asPlayable.- Each class provides its own version of
play(), fulfilling the interface's contract. - Code that only needs to "play something" can accept a
Playablereference and work with either class:Playable p = new MusicTrack("Song"); p.play();
Multiple Interfaces
Because interfaces don't carry implementation state, Java allows a class to implement several of them at once —
something that isn't allowed with class inheritance (a class can only extends one class).
interface Playable { void play(); }
interface Downloadable { void download(); }
class MusicTrack implements Playable, Downloadable {
public void play() { /* ... */ }
public void download() { /* ... */ }
}
default Methods
Since Java 8, interfaces can include default methods — methods with an actual body. This lets you add
new behavior to an interface without breaking every class that already implements it, since existing implementers
automatically inherit the default behavior unless they choose to override it.
interface Playable {
void play();
default void stop() {
System.out.println("Stopped.");
}
}
MusicTrack and VideoClip both get a working stop() for free — they only need to implement play() unless they want custom stop behavior.