Lesson Overview
Learn from operator overloading by designing methods whose names and behaviour fit the domain without hiding surprising work.
Portfolio focus: Design method names for a tiny Money class.
Starter: think before typing
Before running this readable interfaces example, find the line where the main idea becomes active. Write a prediction: what must already be true for that line to work, and what should be different after it runs? The checked run ends with `120p`; predict how the focus line helps produce that evidence.
Learning Objectives
- Explain why some languages let operators call functions.
- Design readable Java methods instead of clever syntax.
- Avoid APIs that look simple but do expensive or surprising work.
- Balance expressiveness against maintainability.
Learning Outcomes
- By the end of the lesson, you can explain why some languages let operators call functions.
- By the end of the lesson, you can design readable Java methods instead of clever syntax.
- By the end of the lesson, you can avoid APIs that look simple but do expensive or surprising work.
- By the end of the lesson, you can balance expressiveness against maintainability.
Why this idea exists
Operator-style API design exists because readable programs often feel close to the language of the problem: adding money, comparing dates, combining paths or applying transformations.
Some languages allow operator overloading so symbols such as `+` can call user-defined behaviour. Java mostly avoids that feature, so Java programmers must design clear method names that carry the same expressive intent without hiding surprising work.
This lesson fits the arc by shifting attention from whether code works to how code reads. A good API makes valid use obvious, invalid use awkward and expensive behaviour visible enough for maintainers to trust.
Deep dive
Mechanism in this example
The important mechanism is visible around `Money price = new Money(100);`. Read it as a concrete move in the program, not as decorative syntax: identify what value, object, branch, call or boundary is being created at that point.
Design pressure
This lesson fits the arc by shifting attention from whether code works to how code reads. A good API makes valid use obvious, invalid use awkward and expensive behaviour visible enough for maintainers to trust.
Failure mode to watch
For Operator-Style API Design, deliberately disturb the assumption behind `Money price = new Money(100);`: use an awkward value, missing input, wrong order of calls or boundary case. The useful question is how that disturbance exposes a weakness in the readable interfaces design.
Extension step
Extend the example by doing this: Explain why Java does not let you overload + for your class. The point is to make one small change that forces you to revisit the concept, rather than adding unrelated features.
Portfolio standard
The portfolio note should not repeat the lesson wording. It should show the edited code, the run result, and your own explanation of this evidence: identify one api that looks neat but hides too much work.
Lesson visual

Type this and run it
Create OperatorStyleApiDesignDemo.java, type the program, and run it before changing anything. This section is about reproducing the checked baseline.
public class OperatorStyleApiDesignDemo {
public static void main(String[] args) {
Money price = new Money(100);
Money tax = new Money(20);
Money total = price.plus(tax);
System.out.println(total);
}
}
record Money(int pence) {
Money plus(Money other) {
return new Money(pence + other.pence);
}
public String toString() {
return pence + "p";
}
}Build and run it with:
javac OperatorStyleApiDesignDemo.java && java OperatorStyleApiDesignDemoExpected baseline: 120p
Run the code in your browser
Use the editor as an experiment surface. First run the checked version, then make one small change to the part of the program that demonstrates readable interfaces and compare the new behaviour with the reference output.
120pLine-by-line explanation
Read the code as a sequence of responsibilities. The focus line for this lesson is Money price = new Money(100);; the surrounding lines prepare it, use its result or make the behaviour observable.
public class OperatorStyleApiDesignDemo {This names the runnable class for the Operator-Style API Design example, giving the compiler and JVM one clear unit to build.
public static void main(String[] args) {This is the program entry point. In Operator-Style API Design, it keeps the demonstration of readable interfaces in one traceable starting script.
Money price = new Money(100);This introduces price as named state for Operator-Style API Design. Later lines can read, update, pass or print that specific value as evidence.
Money tax = new Money(20);This introduces tax as named state for Operator-Style API Design. Later lines can read, update, pass or print that specific value as evidence.
Money total = price.plus(tax);This introduces total as named state for Operator-Style API Design. Later lines can read, update, pass or print that specific value as evidence.
System.out.println(total);This prints total as the observable evidence for Operator-Style API Design. The output lets the learner check whether the readable interfaces idea behaved as predicted.
}This closes the innermost Operator-Style API Design block, so the immediately preceding method, branch or loop has finished.
}This closes the outer Operator-Style API Design structure, returning the reader to the surrounding class or file.
record Money(int pence) {This declares a compact immutable data carrier, useful here because Operator-Style API Design needs a named value with fields.
Money plus(Money other) {This starts plus, a named Operator-Style API Design operation. Its parameters describe what information comes in; its body decides what work is done.
return new Money(pence + other.pence);This sends a Operator-Style API Design result back to the caller, so the surrounding code can use the answer.
}This closing brace number 3 completes another layer of the Operator-Style API Design source structure Java has been checking.
public String toString() {This starts toString, a named Operator-Style API Design operation. Its parameters describe what information comes in; its body decides what work is done.
return pence + "p";This sends a Operator-Style API Design result back to the caller, so the surrounding code can use the answer.
}This closing brace number 4 completes another layer of the Operator-Style API Design source structure Java has been checking.
}This closing brace number 5 completes another layer of the Operator-Style API Design source structure Java has been checking.
Worked example
From code to explanation
Problem: Use Operator-Style API Design to complete a small portfolio-quality step: Design method names for a tiny Money class.
Method: Locate the line `Money price = new Money(100);`, explain the exact role it plays, then decide what you would change to extend the example without changing the whole program.
Reveal worked answer
The checked run should produce `120p`. A strong answer links the result back to readable interfaces: what was created, selected, stored, called or protected, and why that matters for the portfolio task.
Trace the program
Before: Before the key operation, identify the relevant value, object, branch or resource that the readable interfaces concept depends on.
During: Trace `Money price = new Money(100);` as the Operator-Style API Design example executes. Say whether that operation creates data, checks a condition, calls behaviour, stores information or crosses a boundary.
After: Compare the run with the expected evidence: `120p`.
Change: Now explain why java does not let you overload + for your class, run again, and explain the smallest reason the behaviour changed.
Common misconception
A common mistake in operator-style api design is treating the example as a finished answer. For readable interfaces, the important question is narrower: which operation carries the idea, what does it make possible, and what would break if you changed it carelessly?
Quick checks
1. In this Operator-Style API Design example, what is the best reason to focus on `Money price = new Money(100);`?
2. Which evidence is strongest after you edit and rerun this example?
How to study this lesson
For Operator-Style API Design, predict how readable interfaces changes the run before you press Run.
Use the first portfolio task as your main edit: Design method names for a tiny Money class.
Use the second task as your variation: Explain why Java does not let you overload + for your class.
Finish with evidence, not a diary entry: Identify one API that looks neat but hides too much work.
Portfolio Practice
- Design method names for a tiny Money class.
- Explain why Java does not let you overload + for your class.
- Identify one API that looks neat but hides too much work.
Final self-check
Can you explain the key operation?
Explain the line identified in the quick check in one or two sentences. Your answer should say what it does before the output 120p appears.
Can you justify the portfolio evidence?
Your evidence should include the original run, one edited run, and a short note explaining how the edit affected readable interfaces.
Study route
Practise readable interfaces by predicting the Java example, typing it, running it in the browser, tracing the result and saving portfolio evidence.
Next, move into Generic Reuse and carry forward one improvement from this lesson into the next program.
