Interfaces & Abstract Classes
Contracts versus partial implementations, default methods, and when to use which.
On this page
Both interfaces and abstract classes let you program to what something does rather than how. They look similar but serve different purposes. Knowing which to reach for is a hallmark of a thoughtful Java developer.
Interfaces: a pure contract
An interface is a contract: a list of methods a class promises to provide, with no implementation. Any class that implements the interface must fulfill the contract.
A job description lists responsibilities - "must handle payments", "must issue receipts" - without saying how the person does them. Anyone who can fulfill those duties qualifies. An interface is that job description; a class that implements it is the hired employee.
interface Payable {
void pay(double amount); // no body - just the promise
String receipt();
}
class CreditCard implements Payable {
public void pay(double amount) {
System.out.println("Charged $" + amount + " to card.");
}
public String receipt() {
return "Card receipt";
}
}
class PayPal implements Payable {
public void pay(double amount) {
System.out.println("Paid $" + amount + " via PayPal.");
}
public String receipt() {
return "PayPal receipt";
}
}Now any code can accept any Payable and not care which one it is:
void checkout(Payable method, double total) {
method.pay(total);
System.out.println(method.receipt());
}This is the key to flexible code
Because checkout depends on the Payable interface - not on CreditCard or
PayPal specifically - you can add ApplePay, Crypto, or anything else later
without changing checkout at all. This idea, "program to an interface", is one
of the most important in all of software design.
A class can implement many interfaces
Unlike inheritance (one parent only), a class can implement several interfaces - mixing in multiple capabilities:
class Smartphone implements Callable, Camera, MusicPlayer {
// must provide all methods from all three
}Default methods
Interfaces can provide default method implementations, so implementers get behavior for free (and interfaces can evolve without breaking existing code):
interface Greeter {
String name();
default void greet() { // has a body!
System.out.println("Hello, " + name());
}
}Abstract classes: a partial blueprint
An abstract class sits between a normal class and an interface. It can have fields, constructors, fully-written methods, and abstract methods (with no body) that subclasses must complete. You cannot create an object from it directly.
abstract class Employee {
private String name; // state
Employee(String name) { // constructor
this.name = name;
}
String getName() { return name; } // shared behavior
abstract double monthlyPay(); // each subclass MUST define this
}
class Salaried extends Employee {
private double annual;
Salaried(String name, double annual) {
super(name); // call parent constructor
this.annual = annual;
}
@Override
double monthlyPay() { return annual / 12; }
}An interface is a pure contract - a promise with no shared machinery. An abstract class is a partial product - a half-built appliance with some parts installed and a few slots left for you to fill in. Use an interface to define a capability; use an abstract class to share common code among closely related types.
Which should you use?
| Question | Prefer… |
|---|---|
| Do unrelated classes need to share a capability? | Interface |
| Do you need to define a "can-do" role (Comparable, Runnable)? | Interface |
| Do closely related classes share fields and common code? | Abstract class |
| Do you need a constructor or private state? | Abstract class |
| Might a class need several of these behaviors at once? | Interface (multiple allowed) |
Modern guidance
When in doubt, reach for an interface first - they're more flexible, a class can implement many, and default methods cover shared behavior. Use an abstract class when several related types genuinely share state and implementation.
Quick check
You need several UNRELATED classes to each provide a 'save()' capability. What fits best?
Key takeaways
- An interface is a pure contract of methods a class promises to implement; a class can implement many.
- Programming to an interface lets you swap implementations without changing the code that uses them.
- Default methods let interfaces provide shared behavior and evolve safely.
- An abstract class is a partial blueprint with state, constructors, shared code, and abstract methods; it can't be instantiated.
- Prefer interfaces for capabilities and flexibility; use abstract classes to share code among closely related types.
Next, we'll meet modern Java's concise type tools - records, sealed classes, and enums - that make everyday modeling cleaner and safer.