Encapsulation
Why fields go private, and how keeping rules next to data stops callers from breaking your object.
Open this lesson in the learning hubKey points
- Make fields
private. Expose behaviour, not data. Callers ask the object to do things instead of reaching inside. - The point is not secrecy. It is that the rules about the data live next to the data and cannot be skipped.
- A getter and setter for every field is not encapsulation, it is a struct with extra steps. Expose only what is needed.
- Public API is a promise you must keep. Private internals can be rewritten on a Tuesday and nobody notices.
- Package-private (no modifier at all) is the quiet default: visible inside the package, invisible outside it.
Example
public class Main {
static class Thermostat {
private int celsius = 20; // nobody touches this directly
public int celsius() { return celsius; }
public void setCelsius(int value) { // the rule lives with the data
if (value < 5 || value > 30) {
throw new IllegalArgumentException("out of range: " + value);
}
this.celsius = value;
}
public void warmer() { setCelsius(celsius + 1); }
}
public static void main(String[] args) {
Thermostat t = new Thermostat();
t.warmer();
System.out.println("now " + t.celsius() + "C");
try {
t.setCelsius(99);
} catch (IllegalArgumentException e) {
System.out.println("blocked: " + e.getMessage());
}
System.out.println("still " + t.celsius() + "C - invariant held");
}
}
Private data plus public behaviour means your invariants cannot be broken from outside.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the OOP course, and every lesson in it is listed on the OOP contents page.