EMZETT.
Login

Interface

In short: A pure contract of method signatures with no implementation of its own (exceptions: default methods) — a class “promises” with implements to provide all the prescribed methods.

In more detail: Unlike inheritance (only one superclass), a class in Java can implement several interfaces at the same time — this sidesteps the restriction of single inheritance. Interfaces are the basis for making different classes interchangeable via shared behaviour, without needing a shared inheritance hierarchy.

interface Drivable {
    void drive();
}
class Car implements Drivable {
    public void drive() { System.out.println("Vroom"); }
}

In Depth

interface Drivable {
    void drive(); // implicitly "public abstract"
 
    default void honk() { // since Java 8: default implementation possible
        System.out.println("Honk!");
    }
 
    static int maxSpeed() { // static interface method
        return 250;
    }
}
 
interface Swimmable {
    void swim();
}
 
// A class can implement MULTIPLE interfaces at the same time
class AmphibiousVehicle implements Drivable, Swimmable {
    public void drive() { System.out.println("Driving on the road"); }
    public void swim() { System.out.println("Swimming in the water"); }
}
 
Drivable d = new AmphibiousVehicle();
d.drive();
d.honk(); // uses the default implementation, doesn't have to be overridden

default methods were introduced with Java 8 to solve a concrete problem: extending interfaces with new methods after the fact, without breaking ALL existing implementing classes throughout the entire ecosystem (the most famous example is forEach() on Collection, which was only added later as a default method). Static methods on interfaces bundle helper functions that logically belong to the interface but need no concrete implementation. The core difference from an abstract class remains important: an interface (apart from static/final constants) can’t hold any mutable state of its own (instance fields) — that remains reserved for classes.

Functional interfaces

An interface with EXACTLY one abstract method is called a “functional interface” and is the basis for lambda expressions — the @FunctionalInterface annotation has the compiler check that this condition is met:

@FunctionalInterface
interface Operation {
    int calculate(int a, int b);
}
 
Operation addition = (a, b) -> a + b; // lambda instead of a full class
System.out.println(addition.calculate(3, 4)); // 7

java.util.function already provides ready-made, widely reusable functional interfaces like Function<T, R>, Predicate<T>, and Consumer<T>, so no custom interface has to be defined at all for common cases.

Conflicts with multiple default methods

If a class implements two interfaces that both bring a default method with the same name, a conflict arises that the compiler does NOT resolve automatically — the implementing class has to explicitly override the method itself:

interface A { default void greet() { System.out.println("Hello from A"); } }
interface B { default void greet() { System.out.println("Hello from B"); } }
 
class C implements A, B {
    public void greet() { // MUST be overridden, otherwise a compiler error
        A.super.greet(); // can specifically call a particular interface's version
    }
}

This is Java’s deliberately chosen compromise to avoid the diamond problem with default methods, without banning multiple inheritance of interfaces entirely.

See also: Abstraction, Inheritance, Polymorphism, Lambda