Inheritance shares code between closely related classes. But often you care less about what a class is and more about what it can do. A payment might be made by card, bank transfer or gift voucher: very different classes, but they all need a pay(amount) method. A list of products, people or files might all need to be sorted.
An interface describes a set of abilities as method signatures, without the code that performs them. It's a contract: any class that implements the interface promises to provide those methods. Code that uses the interface can then work with any class that keeps the promise, without knowing anything else about it.
Abstract classes sit in between a normal class and an interface: they can hold shared fields and finished methods, while leaving some methods for subclasses to complete. In this lesson you'll write and implement interfaces, use default methods, create abstract classes and learn how to choose between them.
Declaring and implementing an interface
interface Payable {
void pay(double amount);
String method();
}
class CardPayment implements Payable {
public void pay(double amount) {
System.out.println("Charging £" + amount + " to card");
}
public String method() { return "card"; }
}- Interface methods are automatically
publicandabstract: they have no body. implementssays a class keeps the contract. It must provide every method, markedpublic, or the class won't compile.- You can't create an interface directly (
new Payable()), but you can use it as a type:Payable p = new CardPayment();.
Several interfaces and default methods
A class can extend only one class, but it can implement any number of interfaces:
class Printer implements Printable, Scannable, Comparable<Printer> { ... }That's how Java lets an object have many independent abilities. Since Java 8, an interface can also include default methods, which have a body and are inherited by every implementing class unless it overrides them:
interface Greeter {
String name();
default String greet() { return "Hello, " + name() + "!"; }
}Default methods let library authors add features to an interface without breaking every class that already implements it.
Abstract classes
An abstract class is a class that can't be instantiated on its own and may contain abstract methods: methods declared without a body, which subclasses must implement.
abstract class Shape {
private final String label;
Shape(String label) { this.label = label; }
abstract double area(); // each shape must provide this
String describe() { // shared, finished code
return String.format("%s with area %.2f", label, area());
}
}A subclass such as class Square extends Shape must implement area(). Unlike an interface, an abstract class can have constructors, fields with state and any mix of finished and unfinished methods.
Comparable: an interface you'll use often
Java's own libraries are built around interfaces. Implementing Comparable<T> gives your objects a natural order, so Collections.sort() and TreeSet know how to sort them:
class Player implements Comparable<Player> {
int score;
public int compareTo(Player other) {
return Integer.compare(other.score, this.score); // highest first
}
}compareTo returns a negative number, zero or a positive number. Other common library interfaces include Runnable, Iterable and AutoCloseable, and the functional interfaces you'll use with lambdas.
Constants, static methods and sealed interfaces
Interfaces can contain a few other kinds of member:
- Constants: any field declared in an interface is automatically
public static final, soint MAX_ITEMS = 5;is a constant shared by every implementation. - Static methods (Java 8 and later): helpers called on the interface itself, such as
Comparator.naturalOrder()orList.of(...). - Private methods (Java 9 and later): code shared between default methods without becoming part of the public contract.
Since Java 17, an interface can be sealed, listing exactly which classes may implement it. The compiler then knows every possible implementation, so a switch over them needs no default:
sealed interface Shape permits Circle, Square {}
record Circle(double r) implements Shape {}
record Square(double side) implements Shape {}
static double area(Shape s) {
return switch (s) {
case Circle c -> Math.PI * c.r() * c.r();
case Square q -> q.side() * q.side();
};
}If someone adds a new shape to the permits list, every switch that doesn't handle it stops compiling, the same safety you get with enums. The abstraction and interfaces lesson has more practice.
Java Interfaces Syntax
Interface and abstract class syntax
interface Name {
ReturnType method(Type param);
default ReturnType helper() { ... }
}
class Impl implements Name {
public ReturnType method(Type param) { ... }
}
abstract class Base {
abstract ReturnType mustImplement();
ReturnType shared() { ... }
}
class Concrete extends Base {
ReturnType mustImplement() { ... }
}Java Interfaces Summary
- An interface is a contract of method signatures; classes
implementsit and provide the bodies. - A class can implement many interfaces but extend only one class.
- Default methods give interfaces shared behaviour that implementing classes inherit.
- Abstract classes can have state, constructors and finished methods, plus abstract ones to complete.
Comparable<T>gives objects a natural sort order throughcompareTo.
Java Interfaces Examples
Each example shows the code, the output it produces and what each part does.
Payments through one interface
interface Payable {
boolean pay(double amount);
String method();
}
class CardPayment implements Payable {
public boolean pay(double amount) { return amount <= 500; }
public String method() { return "Card"; }
}
class VoucherPayment implements Payable {
private double value;
VoucherPayment(double value) { this.value = value; }
public boolean pay(double amount) { return amount <= value; }
public String method() { return "Voucher"; }
}
public class Main {
static void checkout(Payable p, double amount) {
String result = p.pay(amount) ? "approved" : "declined";
System.out.println(p.method() + " payment of " + amount + ": " + result);
}
public static void main(String[] args) {
checkout(new CardPayment(), 89.99);
checkout(new VoucherPayment(25), 40.0);
}
}Card payment of 89.99: approved
Voucher payment of 40.0: declinedLine-by-line explanation
- Lines 1 to 4The contract: any payment must be able to pay and describe its method.
- Lines 6 to 16Two unrelated classes keep the same contract in different ways.
- Line 19checkout only knows about Payable, so new payment types need no changes here.
An abstract class with shared code
abstract class Shape {
private final String label;
Shape(String label) { this.label = label; }
abstract double area();
String describe() {
return String.format("%s with area %.2f", label, area());
}
}
class Square extends Shape {
private final double side;
Square(double side) { super("Square"); this.side = side; }
double area() { return side * side; }
}
class Triangle extends Shape {
private final double base, height;
Triangle(double b, double h) { super("Triangle"); base = b; height = h; }
double area() { return base * height / 2; }
}
public class Main {
public static void main(String[] args) {
Shape[] shapes = { new Square(3), new Triangle(4, 5) };
for (Shape s : shapes) System.out.println(s.describe());
}
}Square with area 9.00
Triangle with area 10.00Line-by-line explanation
- Line 5Every concrete shape must say how to calculate its area.
- Lines 7 to 9describe() is written once and calls whichever area() the object has.
- Line 14Square passes its label to the abstract class's constructor with super.
- Line 20Triangle does the same.
Sorting with Comparable
import java.util.*;
class Player implements Comparable<Player> {
final String name;
final int score;
Player(String name, int score) { this.name = name; this.score = score; }
public int compareTo(Player other) {
return Integer.compare(other.score, this.score);
}
public String toString() { return name + "=" + score; }
}
public class Main {
public static void main(String[] args) {
List<Player> board = new ArrayList<>(List.of(
new Player("Ana", 120), new Player("Ben", 340), new Player("Cleo", 210)));
Collections.sort(board);
System.out.println(board);
}
}[Ben=340, Cleo=210, Ana=120]Line-by-line explanation
- Line 3Implementing Comparable gives players a natural order.
- Lines 8 to 10Comparing other with this, instead of this with other, sorts highest first.
- Line 19Collections.sort uses compareTo automatically.
Common Java Interfaces Mistakes
Forgetting public when implementing
class CardPayment implements Payable {
boolean pay(double amount) { return true; } // weaker access: compile error
}class CardPayment implements Payable {
public boolean pay(double amount) { return true; }
}Trying to instantiate an abstract class
Shape s = new Shape("Blob"); // Shape is abstract; cannot be instantiatedShape s = new Square(2);Leaving an interface method unimplemented
class VoucherPayment implements Payable {
public boolean pay(double amount) { return true; }
// method() missing: class must be abstract or implement it
}class VoucherPayment implements Payable {
public boolean pay(double amount) { return true; }
public String method() { return "Voucher"; }
}Java Interfaces in Real Projects
Interfaces in professional Java
Large applications are designed around interfaces: a PaymentService interface might have one implementation for the real payment provider and another, fake one for tests. Frameworks such as Spring wire the right implementation in automatically. The standard library's List, Map and Set are themselves interfaces, which is why you declare List<String> names = new ArrayList<>();.
Java Interfaces FAQ
Can an interface have fields or a constructor?
An interface can't have a constructor or ordinary instance fields, because it can't be instantiated and holds no state. It can declare constants, which are automatically public static final. If related classes need shared state, use an abstract class.
What happens if two interfaces have the same default method?
If a class implements both, the compiler forces it to override the method and resolve the conflict. Inside the override, you can call a specific version with InterfaceName.super.method(), for example A.super.hi().
Can an interface extend another interface?
Yes, and it can extend several at once: interface Shape extends Drawable, Comparable<Shape>. A class implementing Shape must then provide the methods of all three interfaces.
What is a functional interface?
An interface with exactly one abstract method, such as Runnable, Comparator or Predicate. Because there's only one method to implement, you can supply it with a lambda expression instead of a full class. The optional @FunctionalInterface annotation asks the compiler to check the rule.
Why program to an interface instead of a class?
Code that depends on an interface type, such as List or Payable, works with any implementation, so you can swap one in without changing that code. It also makes testing easier, because a test can pass in a simple fake implementation instead of a real payment service or database.
Java Interfaces Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Complete the class so it keeps the Drawable contract.
class Logo Drawable {
public void draw() { System.out.println("Drawing logo"); }
}
Complete the declaration of a method subclasses must implement.
abstract class Animal {
String sound();
}
How many interfaces can one class implement?
What does this print?
interface Greeter {
String name();
default String greet() { return "Hi " + name(); }
}
// in main:
Greeter g = () -> "Zoe";
System.out.println(g.greet());
Which can an abstract class have that an interface can't?
Java Interfaces Quiz
5 questions to check what you learned.
What is an interface in Java?
- A class with no methods
- A graphical window
- A type of loop
- A contract of methods that implementing classes must provide
Can you write
new Comparable()?- Yes
- Only inside a list
- No, an interface can't be instantiated directly
- Only with generics
What does
compareToreturn when two objects are equal in order?- true
- 0
- 1
- -1
What is a default method?
- A method that runs automatically
- The first method in a class
- A method with no parameters
- An interface method with a body that implementing classes inherit
When is an abstract class a better choice than an interface?
- When closely related classes share state and code but must each complete a few methods
- When unrelated classes need the same ability
- When a class needs several parents
- Never