Objects, Classes & OOP Design

Interfaces

An interface defines a type by its capabilities alone. Since Java 8 interfaces can carry default and static methods, but their essence is unchanged: they are contracts, and the preferred way to define types shared across a hierarchy.
  • A class implements any number of interfaces — Java's answer to multiple inheritance
  • default methods add behavior without breaking implementors
  • Interface fields are implicitly public static final; methods implicitly public
  • Prefer interfaces to abstract classes for defining types (EJ 20)
  • Use interfaces only to define types — no "constant interfaces" (EJ 22)
  • Refer to objects by their interfaces: List<String> list = new ArrayList<>() (EJ 64)
Interface with a default method
public interface Measurable {
    double getMeasure();                       // abstract — the contract

    default boolean isLargerThan(Measurable other) {
        return getMeasure() > other.getMeasure();  // free behavior for implementors
    }
}

Interfaces carry no instance state, which is why a class can implement many of them safely. Standard fine-grained examples: Comparable, Iterable, AutoCloseable, Runnable — and every functional interface used by lambdas (Functional Interfaces). An interface with exactly one abstract method can be implemented by a lambda expression.

Default method conflict rules: if a class inherits the same default method from two interfaces, it must override and choose (it may delegate via Measurable.super.isLargerThan(other)). If a superclass provides the method, the class wins over any interface default ("class wins").

Sources
  • Core Java, Volume I: Fundamentals (13th ed.)Ch. 6.1 — Interfaces
  • Effective Java (3rd ed.)Items 20–22, 41, 64
  • Learning Java (6th ed.)Ch. 5 — Objects in Java