Lesson 107 min read

Interfaces & Abstract Classes

Contracts your classes promise to follow

Interfaces — A Promise to the World

An interface is like a job description. It says "whoever takes this job must be able to do X, Y, and Z" — but it doesn't say how. Any class that implements the interface is making a promise: "I will provide all these methods."

Why is this powerful? Because other code can work with the interface without caring about the specific class. A Printable interface doesn't care if it's printing a Document, a Photo, or a Receipt — as long as they all have a print() method. Java's built-in interfaces like Comparable power data structures such as binary search trees and sorted collections.

Key differences from classes:

  • Interfaces can't have constructors or instance fields (only constants).
  • A class can implement multiple interfaces (unlike extends, which is limited to one).
  • Since Java 8, interfaces can have default methods with a body.

Defining & Implementing Interfaces

public class Main {
// Interface — the contract
interface Drawable {
void draw(); // any Drawable must have this
}
interface Resizable {
void resize(double factor);
}
// A class can implement MULTIPLE interfaces
static class Circle implements Drawable, Resizable {
double radius;
Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.printf("Drawing circle with radius %.1f%n", radius);
}
@Override
public void resize(double factor) {
radius *= factor;
System.out.printf("Resized to radius %.1f%n", radius);
}
}
static class Square implements Drawable {
double side;
Square(double side) {
this.side = side;
}
@Override
public void draw() {
System.out.printf("Drawing square with side %.1f%n", side);
}
}
public static void main(String[] args) {
// Polymorphism through interfaces
Drawable[] art = { new Circle(5), new Square(3), new Circle(2) };
for (Drawable d : art) {
d.draw(); // Java picks the right version
}
System.out.println("---");
Circle c = new Circle(10);
c.resize(0.5);
c.draw();
}
}
Output
Drawing circle with radius 5.0
Drawing square with side 3.0
Drawing circle with radius 2.0
---
Resized to radius 5.0
Drawing circle with radius 5.0

Default Methods & Abstract vs Interface

Since Java 8, interfaces can include default methods — methods with a body that classes inherit for free. This lets you add new methods to an interface without breaking all existing implementations.

When to use which?

  • Use an interface when you want to define a capability that many unrelated classes can share. Think "can fly" (Flyable), "can be serialized" (Serializable).
  • Use an abstract class when you have a family of related classes that share common code. Think "all animals eat and sleep, but make different sounds."
  • Use both together when you need shared behavior (abstract class) plus additional capabilities (interfaces).

Default Methods & Combining Abstract + Interface

public class Main {
// Interface with default method
interface Greetable {
String getName();
// Default method — classes get this for free
default void greet() {
System.out.println("Hello! I'm " + getName());
}
}
interface Farewell {
String getName();
default void sayBye() {
System.out.println("Goodbye from " + getName() + "!");
}
}
// Implements both interfaces
static class Person implements Greetable, Farewell {
private String name;
Person(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
// Can override default methods too
@Override
public void greet() {
System.out.println("Hey there! The name's " + name + ".");
}
}
static class Robot implements Greetable {
@Override
public String getName() {
return "RoboHelper-3000";
}
// Uses the default greet() — no override needed
}
public static void main(String[] args) {
Person alex = new Person("Alex");
alex.greet(); // overridden version
alex.sayBye(); // default version
Robot bot = new Robot();
bot.greet(); // default version
}
}
Output
Hey there! The name's Alex.
Goodbye from Alex!
Hello! I'm RoboHelper-3000
Note: Here's a handy rule of thumb: Interfaces define what a class CAN DO (capabilities), while abstract classes define what a class IS (identity). A Bird IS an Animal (abstract class) and CAN Fly (interface). A Plane IS a Vehicle and also CAN Fly. The Flyable interface connects unrelated things that share a capability.

Quick check

How many interfaces can a Java class implement?
Inheritance & PolymorphismCollections Framework