Command Palette

Search for a command to run...

PHASE 5Intermediate ~27 min· topic 7 of 13

Topic 5.7

Interfaces

In one line

An interface is a named list of abilities, a contract, that any class can promise to provide with implements. A class can implement many interfaces, and code written against an interface works with every class that implements it.

Think of it like this

A wall socket. The socket doesn't care whether you plug in a phone charger, a lamp or a kettle. It only cares that the plug has the right shape. Anything with that plug works. An interface is the plug shape: a promise about what something can do, with no say in how it's built inside.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

Interface
A type that lists methods (a contract) without saying how they work. Declared with the keyword interface.
implements
The keyword a class uses to promise it provides all the methods of an interface.
Contract
The promise an interface makes: any object of this type has these methods with this meaning.
Implicitly public abstract
Interface methods without a body are automatically public and abstract, even if you don't write those words.
Constant
A public static final field. All fields in an interface are constants.
Marker interface
An interface with no methods, used only as a label, like Serializable.
Program to an interface
Declare variables and parameters with interface types (List) rather than concrete classes (ArrayList) so implementations can change.

Step by step

01Writing the contract

An online shop accepts cards and UPI. The checkout doesn't care how money moves, only that it can ask 'pay this amount' and get yes or no. That's the contract.

boolean pay(double amount); has no body and no modifiers, yet it is public abstract. Writing public abstract explicitly is legal but redundant.

Main.javawhole filejava
interface PaymentMethod {
    boolean pay(double amount);   // public abstract, implicitly
    String name();
}

02Fulfilling it with implements

Each class says implements PaymentMethod and provides a body for both methods. These bodies must be public, because the interface's methods are public. Forgetting public is the most common interface compile error.

Card and Upi share no code and no parent class (apart from Object), yet both can be passed anywhere a PaymentMethod is expected.

Main.javawhole filejava
class Card implements PaymentMethod {
    private double limit;
    Card(double limit) { this.limit = limit; }
    public boolean pay(double amount) {
        if (amount > limit) return false;
        limit -= amount;
        return true;
    }
    public String name() { return "Card"; }
}

03Depend on the interface, not the class

Checkout receives a PaymentMethod in its constructor and never mentions Card or Upi. Add a Wallet class next year and Checkout doesn't change. This is the dependency inversion principle and the core of the Strategy pattern (System Design course, /topic/phase-2/strategy).

It also makes testing easy: pass a fake PaymentMethod that always returns true.

Depend on the interface, not the classdiagram
Rendering diagram…

04Many interfaces, one class

A Duck can swim and fly; a Fish can only swim; a Plane can only fly. These capabilities don't fit a single family tree: is Duck under Swimmer or under Flyer? With interfaces it doesn't matter. Duck implements both.

Because interface methods (originally) had no bodies, implementing two interfaces that both declare void move() causes no conflict: the class writes one move() that satisfies both. Default methods add a wrinkle, which Topic 5.8 resolves.

05Interface constants

int MAX_ALTITUDE = 1000; inside an interface is public static final. Every implementing class can use the bare name, and others can write Flyer.MAX_ALTITUDE. You cannot assign to it.

Effective Java warns against the constant interface anti-pattern: implementing an interface just to get short names for constants leaks those constants into your class's public API. Put constants in a final class or an enum, and use import static.

terminal
$ javac Main.java
── expected output ──
Main.java:2: error: cannot assign a value to static final variable MAX
public class Main { public static void main(String[] a) { Limits.MAX = 20; } }
^
1 error

06Interfaces you already use

Comparable<T> (one method, compareTo) lets Collections.sort order your objects. Runnable (one method, run) is what threads execute (Topic 13.1). List, Set, Map are interfaces; ArrayList, HashSet, HashMap are classes implementing them (Phase 9). AutoCloseable makes try-with-resources work (Topic 7.6).

An interface with exactly one abstract method is a functional interface, and you can implement it with a lambda instead of a class. That's Phase 10's whole story.

Try it yourself

  1. 1

    Add a third payment method

    Add class Wallet implements PaymentMethod with a fixed cashback message in pay(). Use it with Checkout without changing Checkout at all.

  2. 2

    Drop the public

    In the Duck example, remove public from Duck.swim() and compile. Read the 'weaker access privileges' error and put it back.

  3. 3

    Sort the other way

    Change Student's compareTo so it sorts by name alphabetically (return name.compareTo(other.name);). Predict [Asha(82), Ravi(95), Zoya(88)] and run.

Code & diagrams

A payment contract with two implementations New tab
Sign in to run this example in your browser.

Expected output

Shoes via Card: paid
Watch via Card: declined
Book via UPI: paid
One class, several interfaces New tab
Sign in to run this example in your browser.

Expected output

Duck paddles
Fish swims
Duck flies up to 1000 m
Plane flies
Duck is a Swimmer: true
Duck is a Flyer:   true
Flyer.MAX_ALTITUDE = 1000
Implementing a JDK interface: Comparable New tab

Collections.sort was written years before Student existed. The Comparable contract is what connects them. More in Topic 9.10.

Sign in to run this example in your browser.

Expected output

[Ravi(95), Zoya(88), Asha(82)]

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Implement an interface method without public

Implement greet() with package-private access.

Main.javawhole filejava
interface Greeter { void greet(); }
class En implements Greeter { void greet() { } }
terminal
$ javac Main.java
── what you'll see ──
Main.java:2: error: greet() in En cannot implement greet() in Greeter
class En implements Greeter { void greet() { } }
^
attempting to assign weaker access privileges; was public
1 error

Break #2

Instantiate an interface

Write new Greeter().

Main.javawhole filejava
interface Greeter { void greet(); }
public class Main { public static void main(String[] a) { Greeter g = new Greeter(); } }
terminal
$ javac Main.java
── what you'll see ──
Main.java:2: error: Greeter is abstract; cannot be instantiated
public class Main { public static void main(String[] a) { Greeter g = new Greeter(); } }
^
1 error

Myth vs fact

Myth

Interfaces can't contain any code.

Fact

That was true before Java 8. Interfaces can now have default, static and (since Java 9) private methods with bodies. They still can't have instance fields or constructors.

Myth

Implementing an interface is a kind of inheritance of code.

Fact

Classically it's inheritance of *type*: you promise behaviour. Default methods do add inherited code, but never inherited state.

Myth

Fields declared in an interface are per-object.

Fact

They are public static final constants shared by everyone. Interfaces have no per-object state.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    invokeinterface dispatch: since the same interface method can sit at a different vtable index in every implementing class, HotSpot searches the class's itable (a list of interface → method-table offsets). Inline caches make monomorphic interface calls as cheap as class calls; at megamorphic sites, itable stubs are a little more expensive than vtable stubs.

  • ▸

    Adding a new abstract method to a published interface breaks every implementer: source fails to compile, and old binaries throw AbstractMethodError when the new method is called. That's why Java 8 added default methods: so Collection.stream() and Iterable.forEach() could be added without breaking every collection class in the world.

  • ▸

    The Java Language Specification says an interface implicitly declares public abstract versions of Object's public methods if it doesn't declare them. That's why you can call toString() on an interface-typed variable, and why Comparator can declare boolean equals(Object) without breaking its functional-interface status (it doesn't count as an abstract method).

  • ▸

    Interfaces are the backbone of dependency injection: Spring and similar frameworks wire PaymentMethod implementations into Checkout at start-up. See the System Design course's Dependency Injection topic (/topic/phase-2/dependency-injection).

Remember this

  1. 1

    An interface declares methods that implementing classes must provide: interface PaymentMethod { boolean pay(double amount); }. Methods without a body in an interface are implicitly public abstract, so you don't write those words.

  2. 2

    A class promises to fulfil the contract with implements: class Card implements PaymentMethod. It must provide a public body for every abstract method, or be declared abstract. The compiler checks this.

  3. 3

    A class can implement many interfaces (class Duck implements Swimmer, Flyer), even though it can extend only one class. Interfaces model *capabilities* that cut across unrelated classes: a Duck, a Submarine and a Fish can all be Swimmers.

  4. 4

    An interface is a type. You can declare variables, parameters and lists of it: PaymentMethod m = new Card();, List<Swimmer>. Calls through it are dispatched to the real object (invokeinterface, Topic 5.4). Program to the interface: List<String> names = new ArrayList<>(); lets you swap implementations later.

  5. 5

    Fields in an interface are implicitly public static final: constants, not per-object state. Interfaces have no constructors and no instance fields. Since Java 8 they may also contain default and static methods, and since Java 9 private methods (Topic 5.8).

  6. 6

    Interfaces can extend other interfaces, even several: interface ReadWrite extends Readable, Writable. Some interfaces declare no methods at all (marker interfaces such as Serializable and Cloneable); they just tag a class for code that checks with instanceof.

Explain it without notes

01

What is an interface, and what does a class promise when it implements one?

02

Why can a class implement many interfaces but extend only one class?

03

What does 'program to an interface' mean, and why is it useful?

04

What are the implicit modifiers of methods and fields in an interface?

Practice

01

Create an interface Shape with double area() and implement it in Circle and Square. Compute the largest area in a List<Shape>.

02

Create interfaces Readable (String read()) and Writable (void write(String s)) and a ReadWrite interface extending both. Implement it with a class that stores the last written string.

03

Make Product(String name, double price) implement Comparable<Product> by price ascending and sort a list.

Trade-offs

  • ↔

    Interfaces decouple callers from implementations, but every interface is another file and another indirection. An interface with exactly one implementation and no plans for more (and no test doubles) can be premature abstraction.

  • ↔

    Interfaces can't hold state, so shared fields and helper logic must live elsewhere: in default methods (no state), in an abstract helper class, or in a composed object.

Done when you can

  • Done when you can declare an interface and implement it in two unrelated classes.

  • Done when you can implement several interfaces in one class and use each as a type.

  • Done when you know interface methods are public abstract and fields are constants.

  • Done when you can implement Comparable and sort your own objects.

  • Done when you can explain 'program to an interface' with an example.