What is encapsulation?
If any code can change an object’s fields, any code can break it. For example, someone could set a bank balance to -500. Encapsulation fixes this. The object’s data (its state) and the methods that guard it sit together behind a boundary. In Java, you keep fields private and offer only the methods callers need.
Other code asks the object to do something instead of changing its fields directly.
privatefields: only the same class can read or write them directly.- Query methods or getters: methods that return a value, such as
getContent(), when callers need to see it. - Behavior methods: make valid changes, such as
withdraw(amount), and enforce the rules (for example, refuse to go below zero). - Setters: methods that overwrite a field. They are optional. A setter for every field lets callers put the object in an invalid state, which weakens encapsulation.
Why use it?
- Control: You can check values before they are stored, or make a field read-only (a getter but no setter).
- Flexibility: You can change how data is stored inside the class (for example, a list instead of an array) without breaking code that calls the getters and setters.
- Safety: External code cannot put the object in an invalid state by setting fields directly.
Example
public class EditorMemento {
// Private = no one from outside can touch 'content' directly
private final String content;
public EditorMemento(String content) {
this.content = content;
}
// Final field and no setter, so it cannot change after creation
public String getContent() {
return content;
}
}public class NotificationService {
private NotificationChannel notificationChannel; // Private dependency
public NotificationService(NotificationChannel channel) {
this.notificationChannel = channel;
}
public void notify(String msg) {
notificationChannel.send(msg); // Use the dependency, don't expose it
}
}- In the first example,
contentis private andfinal, so it is set once in the constructor. Outside code can read it withgetContent(). Because it isfinalwith no setter, the memento cannot change. - In the second, the dependency (
NotificationChannel) is stored in a private field and used only inside the class. Callers callnotify(...). They do not need to know about the channel or touch it.
Where you see it in this repo
- Builder:
BurgerMealhasprivate finalfields; built only via the builder, no direct field access. - Singleton:
JudgeAnalyticsholds state in private fields, access via getters. - Observer:
YouTubeChannelkeeps itsList<Subscriber> subscribersprivate; it notifies them internally. - Memento:
EditorMementohasprivate final String contentand onlygetContent(). - SOLID: DIP/OCP/SRP examples use private fields and constructor or method parameters to pass dependencies and data.