🔌 Interfaces & Abstraction · Intermediate

Interfaces as contracts in Java

What a type can do, not how; implements.

🧩 The mysteryYour checkout code must accept cards, PayPal and a payment method nobody has invented yet. How can code work with classes that don't exist?

A promise, not a recipe

An interface lists WHAT a type can do, never HOW. Think of a wall socket: any appliance with the right plug works, whatever is inside it. A method without a body, like double area();, is automatically public and abstract. And you can't write new Shape() — a contract alone can't do any work.

interface Shape {
    double area();
}

Signing the contract

A class signs with implements — meaning "I promise to provide all these methods". It must give every abstract method a body. Forget one, and the class either has to be declared abstract itself or it won't compile.

class Square implements Shape {
    double side = 2;
    public double area() {
        return side * side;
    }
}
🔮 Predict it

Same call, different body

The variable is a Pet, the object is a Fish. What prints?

interface Pet { String hi(); }
class Fish implements Pet {
    public String hi() { return "Blub"; }
}
void main() {
    Pet p = new Fish();
    System.out.println(p.hi());
}
  1. Blub
  2. null
  3. Compile error: Pet's hi() has no body
Show the answer

The variable's type decides which methods you may call; the actual object decides which body runs. p is declared Pet, but the object is a Fish, so Fish's body runs. Add a Dog class and the same p.hi() line could print "Woof".

⚠️ The trap

The missing public

Interface methods are implicitly public. If your class implements one without writing public, it gets package-private access — weaker than public. An override can never reduce visibility, so this is a compile error, not a runtime surprise.

interface Greeter { String greet(); }
class Hi implements Greeter {
    String greet() { return "hi"; } // error
}
🤔 Think first

Half a promise

Engine declares start() and stop(). class Car implements Engine only writes start(). What does the compiler say?

Think about it, then reveal the answer

Compile error: Car is not abstract and does not override stop(). Either implement stop() or declare abstract class Car and let a subclass finish the job.

💼 In the real world

Plug in, don't rewrite

Checkout code that only calls PaymentMethod.pay(amount) never changes when the team adds Apple Pay: you write one new class that implements PaymentMethod, and it just plugs in. The same trick lets tests swap a real payment gateway for a fake one.

Key takeaways

  1. Interface methods without a body are implicitly public and abstract
  2. implements = 'I promise to provide all these methods'
  3. Miss one method and the class must be abstract, or it won't compile
  4. You can't write new Shape() when Shape is an interface

💡 A wall socket is a contract: any appliance with the right plug works, whatever is inside it.

🤯 Did you know?

Runnable has been in Java since version 1.0 in 1996 — and it is still the same tiny contract: one method, run().

Practice questions

Does this compile?

interface Greeter {
    String greet();
}
class Hi implements Greeter {
    String greet() { return "hi"; }
}
  1. Yes, it compiles fine
  2. No: greet() in Hi must be public
  3. No: Hi must be declared abstract
  4. It compiles, but calling greet() fails at runtime
Check your answer

No: greet() in Hi must be public. Greeter.greet() is implicitly public. Hi's version has package-private access, which is weaker, and an override may never reduce visibility.

What does this print?

interface Animal { String sound(); }
class Dog implements Animal {
    public String sound() { return "Woof"; }
}
class Cat implements Animal {
    public String sound() { return "Meow"; }
}
void main() {
    for (Animal a : List.of(new Cat(), new Dog()))
        System.out.println(a.sound());
}
  1. Meow Woof
  2. Woof Meow
  3. Animal Animal
  4. Compile error
Check your answer

Meow Woof. The variable type Animal decides which methods you may call; the actual object decides which body runs. The list holds a Cat then a Dog.

Next: a duck that flies AND swims. Java allows only one parent class — so how can one class sign two contracts?