Loading published curriculum…

02 · Objects and collections / LESSON 5 OF 102

Interfaces and constructor injection

Depend on a capability rather than one concrete implementation.

Before this lesson: Classes and encapsulation

Understand the topic

Interfaces define contracts. Implementations provide behavior, and overriding selects behavior from the actual object at runtime. Constructor injection means passing required collaborators into a constructor; it works without Spring.

A service depending on an interface can use a console implementation today and a test double tomorrow. Keep required collaborators final. Avoid creating them inside business methods.

EXAMPLE · JAVA

Main.java

interface Notifier { void send(String message); }
class ConsoleNotifier implements Notifier {
    public void send(String message) { System.out.println(message); }
}
class TaskService {
    private final Notifier notifier;
    TaskService(Notifier notifier) { this.notifier = notifier; }
    void finish() { notifier.send("Task completed"); }
}
public class Main {
    public static void main(String[] args) {
        new TaskService(new ConsoleNotifier()).finish();
    }
}

What to expect

Task completed

YOUR TURN

Put it into practice

  1. 01Implement a silent notifier.
  2. 02Build a fake that records its last message.
  3. 03Swap implementations without editing TaskService.

Pass a quiz or complete a lab to check today’s streak. Each lesson counts once per day, including when you review it later.

UNDER THE HOOD

Build the mental model

An interface should express what a client needs rather than mirror every method on an implementation.

  1. 01Constructor injection makes dependencies visible at creation time. Tests can supply a recording fake without running a mail server.
  2. 02An implementation must honor the interface contract, including error behavior. Substitutability fails if one implementation silently ignores required work.
  3. 03Composition lets you combine a service with a notifier. Inheritance is appropriate only when the subtype can safely replace the base type.

A mistake worth avoiding

Creating a new collaborator inside a service method bypasses injected substitutes.

DEBUGGING ROOM

Something broke. Where do you look?

A unit test unexpectedly sends a real notification.

Before revealing the diagnosis, write down your first investigation step.

CHECK YOUR UNDERSTANDING

Which change makes a service easiest to test?

Choose one answer

BUILD IT YOURSELF

Replace side effects with a recording fake

  1. 1.Define an interface for task notifications.
  2. 2.Implement a fake storing messages in a list.
  3. 3.Assert finishing a task sends exactly one expected message.

Acceptance checklist

Lab completion is your self-report. Knowledge checks do not certify project quality.

RETRIEVE IT FROM MEMORY

What should an interface promise about failure?

Revisit this lesson in three days after a successful check or lab.

Ready for the next step?

Explain the dependency boundary and injection.

Reading is separate from passing a knowledge check or completing a lab.

Go deeper · official references