Interfaces in Java

Naveen AnamaneniUpdated · 5 min read

An electricity bill, a mobile recharge and a school fee have nothing in common as things, yet a bill-payment app treats them all the same way: each has an amount due and can be paid. An interface captures exactly that kind of shared ability. It's a contract: a list of methods that a class promises to provide. Any class, from any family tree, can sign it with implements, and code can then work with every signer through the interface type.

Declaring and Implementing

Unrelated classes, one contract
Bills.java▶ Try it
public class Bills {
    interface Billable {
        String payee();
        long amountDue();
    }
 
    static class ElectricityBill implements Billable {
        private final int units;
        ElectricityBill(int units) { this.units = units; }
 
        public String payee() { return "Electricity board"; }
        public long amountDue() { return units * 7L; }
    }
 
    static class MobileRecharge implements Billable {
        public String payee() { return "Mobile operator"; }
        public long amountDue() { return 299; }
    }
 
    static class SchoolFee implements Billable {
        private final String student;
        SchoolFee(String student) { this.student = student; }
 
        public String payee() { return "School fee for " + student; }
        public long amountDue() { return 18500; }
    }
 
    public static void main(String[] args) {
        Billable[] bills = {
            new ElectricityBill(240),
            new MobileRecharge(),
            new SchoolFee("Advitha")
        };
        long total = 0;
        for (Billable b : bills) {
            System.out.println(b.payee() + ": Rs. " + b.amountDue());
            total += b.amountDue();
        }
        System.out.println("Total: Rs. " + total);
    }
}
Output
Electricity board: Rs. 1680
Mobile operator: Rs. 299
School fee for Advitha: Rs. 18500
Total: Rs. 20479

How it works

  1. interface Billable declares two methods with no bodies. Interface methods are public abstract by default, so you don't write those words.
  2. implements Billable is the class's promise to provide both methods. The implementations must be public.
  3. Billable is a type: the array, the loop variable and any parameter can use it. The three classes share no parent other than Object, yet one loop handles them all.

Try it yourself: add a WaterBill that charges Rs. 4 per kilolitre and add it to the array.

What an Interface Can Contain

MemberImplicit modifiersSince
Abstract methodspublic abstractJava 1.0
Constants (fields)public static final: always constantsJava 1.0
default methods with a bodypublicJava 8
static methodspublic (or private)Java 8
private helper methodsprivateJava 9
Nested typespublic staticJava 1.0

What it can't have: instance fields, constructors, or instance initializer blocks. An interface has no object state of its own. Default, static and private methods get their own lesson.

The Errors You'll Meet

E2.java
interface Greeter { String greet(String n); int LIMIT = 3; }
class G implements Greeter {
    String greet(String n) { return n; }
    void f() { LIMIT = 4; }
}
Compiler output
E2.java:3: error: greet(String) in G cannot implement greet(String) in Greeter
    String greet(String n) { return n; }
           ^
  attempting to assign weaker access privileges; was public
E2.java:4: error: cannot assign a value to static final variable LIMIT
    void f() { LIMIT = 4; }
               ^
2 errors

And new Greeter() fails just like an abstract class: Greeter is abstract; cannot be instantiated.

Interfaces in the JDK

You already use interfaces every day:

InterfaceContractImplemented by
List<E>An ordered collectionArrayList, LinkedList
Comparable<T>"I can be compared"String, Integer, LocalDate
Runnable"I can be run"Tasks given to threads
CharSequence"I'm a sequence of characters"String, StringBuilder

That's why the advice is List<String> names = new ArrayList<>();: the variable uses the interface type, so the implementation can change in one place.

Common Mistakes

Leaving out public on implementing methods. It's the most common interface compile error.

Putting state in an interface. Fields in an interface are constants; there's no per-object data.

"Constant interfaces". An interface used only to hold constants pollutes every implementing class; use a final class with static constants or an enum.

Interview Corner

What is an interface in Java?

An interface is a reference type that defines a contract: abstract methods a class promises to implement, plus optional constants, default, static and private methods. A class implements it with implements and must provide public implementations of all abstract methods, unless the class is abstract. Interfaces can't be instantiated and have no instance state. They allow unrelated classes to be treated through a common type, and a class can implement many of them.

Why must methods implementing an interface be public?

Interface methods are implicitly public, and an implementation can't reduce access. A package-private implementation fails with "attempting to assign weaker access privileges; was public".

Practice

  1. Easy: Create an interface Playable with void play(), and implement it in Song and Video. Call play() on each through a Playable[] array.
  2. Harder: Write a method static Billable largest(Billable[] bills) that returns the bill with the highest amount due, and print its payee.

Quick check: Interfaces

4 questions
1Which keyword makes a class follow an interface?
2What are interface methods without a body by default?
3What are fields declared in an interface?
4Can you write new Billable()?

Key Takeaways

Was this tutorial helpful?

Lesson 134 of 482