00:00

Interface in Java – Contracts, Default Methods and Multiple Inheritance

An interface in Java is a reference type that defines a contract: a set of methods that implementing classes promise to provide. A class implements an interface and supplies the method bodies; code that uses the interface type works with every implementation.

Interfaces are the main tool for abstraction and for multiple inheritance of type in Java. Since Java 8 they can also contain default and static methods, and since Java 9 private methods. This tutorial covers all of it with runnable examples.

1. Declaring and Implementing an Interface

Syntax
[public] interface InterfaceName [extends Interface1, Interface2] {
    // constants           (public static final)
    // abstract methods    (public abstract)
    // default methods     (Java 8)
    // static methods      (Java 8)
    // private methods     (Java 9)
}

class ClassName [extends Parent] implements InterfaceName, OtherInterface { ... }
InterfaceBasics.java
public class InterfaceBasics {
    interface Shape {
        double PI_APPROX = 3.14;          // implicitly public static final
        double area();                    // implicitly public abstract
        String name();
    }

    static class Square implements Shape {
        private final double side;
        Square(double side) { this.side = side; }
        public double area() { return side * side; }   // must be public
        public String name() { return "Square"; }
    }

    static class Circle implements Shape {
        private final double r;
        Circle(double r) { this.r = r; }
        public double area() { return PI_APPROX * r * r; }
        public String name() { return "Circle"; }
    }

    public static void main(String[] args) {
        Shape[] shapes = { new Square(3), new Circle(2) };   // interface as a type
        for (Shape s : shapes) System.out.println(s.name() + " area = " + s.area());
        System.out.println("Constant via interface: " + Shape.PI_APPROX);
    }
}
Output
Square area = 9.0
Circle area = 12.56
Constant via interface: 3.14
  • Interface methods without a body are implicitly public abstract.
  • Fields are implicitly public static final constants.
  • Implementing methods must be public, because you cannot reduce visibility.
  • An interface can be used as a variable, parameter, array or return type.

2. What an Interface Can Contain

MemberSinceImplicit modifiers / notes
Constants1.0public static final; must be initialised
Abstract methods1.0public abstract
Default methods8public; have a body; inherited and overridable
Static methods8public by default; called as Interface.method(); not inherited
Private methods9Helpers for default/static methods; not visible outside
Nested types1.1Implicitly public static

An interface cannot have instance fields, constructors or initializer blocks, and cannot be instantiated.

3. Multiple Inheritance with Interfaces

A class can extend only one class but implement any number of interfaces, so an object can have several types at once:

MultipleInterfaces.java
public class MultipleInterfaces {
    interface Flyable  { void fly(); }
    interface Swimmable { void swim(); }

    static class Animal {
        final String name;
        Animal(String name) { this.name = name; }
    }

    // One superclass, many interfaces
    static class Duck extends Animal implements Flyable, Swimmable {
        Duck() { super("Duck"); }
        public void fly()  { System.out.println(name + " flies over the lake"); }
        public void swim() { System.out.println(name + " paddles on the water"); }
    }

    static void takeOff(Flyable f) { f.fly(); }
    static void dive(Swimmable s)  { s.swim(); }

    public static void main(String[] args) {
        Duck d = new Duck();
        takeOff(d);          // a Duck is a Flyable
        dive(d);             // ... and a Swimmable
        System.out.println("instanceof Flyable? " + (d instanceof Flyable));
    }
}
Output
Duck flies over the lake
Duck paddles on the water
instanceof Flyable? true

This avoids the "diamond problem" of multiple class inheritance, because interfaces do not carry instance state. If two interfaces supply conflicting default methods, the class must override the method and can choose one with InterfaceName.super.method(); see Default Methods.

4. Default, Static and Private Methods

Modern interfaces can provide behaviour, not just declarations. This discount API uses all three kinds of method bodies:

ModernInterface.java
import java.util.List;

public class ModernInterface {
    interface Discount {
        double apply(double price);                         // abstract

        default Discount then(Discount next) {              // default method (Java 8)
            return price -> next.apply(apply(price));
        }

        static Discount percent(double p) {                 // static method (Java 8)
            check(p);
            return price -> price * (1 - p / 100);
        }

        static Discount flat(double amount) {
            return price -> Math.max(0, price - amount);
        }

        private static void check(double p) {              // private method (Java 9)
            if (p < 0 || p > 100) throw new IllegalArgumentException("percent out of range: " + p);
        }
    }

    public static void main(String[] args) {
        Discount festive = Discount.percent(10).then(Discount.flat(200));
        System.out.println("Price after discounts: " + festive.apply(5_000));

        List<Discount> options = List.of(Discount.percent(25), Discount.flat(1_000), festive);
        double best = options.stream().mapToDouble(d -> d.apply(5_000)).min().orElseThrow();
        System.out.println("Best price: " + best);
    }
}
Output
Price after discounts: 4300.0
Best price: 3750.0
  • Default methods add behaviour to every implementation, which lets libraries evolve interfaces (as List.sort and Map.forEach were added in Java 8) without breaking existing classes.
  • Static methods are factories and utilities that belong to the interface.
  • Private methods share code between default and static methods without exposing it.
  • Discount has a single abstract method, so it is also a functional interface and can be implemented with lambdas.

5. Interfaces Extending Interfaces

An interface can extend one or more interfaces, combining their contracts:

InterfaceExtends.java
public class InterfaceExtends {
    interface Readable  { String read(); }
    interface Writable  { void write(String data); }
    interface ReadWrite extends Readable, Writable { }   // an interface can extend many

    static class MemoryFile implements ReadWrite {
        private final StringBuilder content = new StringBuilder();
        public String read() { return content.toString(); }
        public void write(String data) { content.append(data); }
    }

    public static void main(String[] args) {
        ReadWrite f = new MemoryFile();
        f.write("Hello, ");
        f.write("interfaces!");
        Readable r = f;                       // view it through a narrower interface
        System.out.println(r.read());
    }
}
Output
Hello, interfaces!

6. Special Kinds of Interfaces

  • Functional interface: exactly one abstract method; the target type of lambdas (Runnable, Comparator, Function).
  • Marker interface: no methods; marks a capability (Serializable, Cloneable).
  • Nested interface: declared inside a class or interface (Map.Entry).
  • Sealed interface (Java 17): sealed interface Shape permits Circle, Square {} limits which classes may implement it, enabling exhaustive switch pattern matching.

7. Interface vs Abstract Class

AspectInterfaceAbstract class
Keyword to use itimplementsextends
How many per classManyOne
Instance fieldsNo (only constants)Yes
ConstructorsNoYes
Method visibilitypublic (or private helpers)Any
Typical roleCapability or API contractShared base implementation

See Abstract Class vs Interface for a detailed comparison.

8. Best Practices

  • Program to interfaces: declare List<String> names = new ArrayList<>(); rather than ArrayList<String>.
  • Keep interfaces small and focused (interface segregation principle).
  • Name them after a capability or role: Comparable, PaymentGateway, Repository.
  • Avoid "constant interfaces" that exist only to hold constants; use a final class or enum instead.
  • Use default methods for genuine shared behaviour or API evolution, not to turn interfaces into abstract classes.

9. Summary

  • An interface defines a contract that classes implement with implements.
  • Abstract methods are public abstract; fields are public static final constants.
  • Java 8 added default and static methods; Java 9 added private methods.
  • A class can implement many interfaces, and an interface can extend many interfaces.
  • Interfaces enable abstraction, polymorphism and loose coupling.

Related Tutorials