Interfaces and Abstract Classes
Two ways to define a contract without full implementation, and how to choose between them.
2 min read
Sometimes you want to say "any class of this kind must be able to do X" without necessarily providing the implementation yourself. Java gives you two tools for that: interfaces and abstract classes. They overlap in purpose but differ in an important way.
Interfaces
An interface defines a contract — a set of method signatures any implementing class must provide — with no state and (traditionally) no implementation of its own.
public interface Playable {
void play();
void pause();
}
public class MusicTrack implements Playable {
@Override
public void play() {
System.out.println("Playing music...");
}
@Override
public void pause() {
System.out.println("Paused.");
}
}Any class that implements Playable is guaranteed, by the compiler, to provide play() and pause(). A class can implement multiple interfaces, which is how Java works around only allowing single class inheritance:
public class SmartSpeaker implements Playable, Connectable {
// must implement every method from both interfaces
}Since Java 8, interfaces can also include default methods with a body, giving implementing classes a usable fallback they can optionally override:
public interface Playable {
void play();
default void stop() {
System.out.println("Stopped.");
}
}Abstract classes
An abstract class sits between a regular class and an interface: it can hold real fields, constructors, and fully implemented methods, alongside abstract methods that subclasses are required to implement. It cannot be instantiated directly with new.
public abstract class Shape {
String color;
public Shape(String color) {
this.color = color;
}
abstract double area(); // no body -- subclasses must provide one
void describe() {
System.out.println("A " + color + " shape with area " + area());
}
}
public class Circle extends Shape {
double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
double area() {
return Math.PI * radius * radius;
}
}Choosing between them
- Use an interface when unrelated classes need to guarantee the same capability (
Playable,Comparable,Runnable) without sharing a common ancestor or any state. - Use an abstract class when you have closely related classes that share actual state and behavior, plus some behavior each subclass must define itself, and single inheritance is not a limitation for your case (since a class can extend only one abstract class).
A useful rule of thumb from the Java standard library: favor interfaces for defining what something can do, and abstract classes for sharing real implementation among a family of closely related types. Modern Java code, especially since default methods arrived, leans heavily toward interfaces for most contracts.
Test what you just learned
4 quick questions. Get all of them right to unlock the next lesson.
You can take the quiz without an account — logging in just lets your result count toward your progress.