Skip to content

Encapsulation

Encapsulation means keeping an object’s data (state) hidden from the outside and only allowing access through controlled methods.

Stage 1intro2 min read

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.

  • private fields: 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, content is private and final, so it is set once in the constructor. Outside code can read it with getContent(). Because it is final with 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 call notify(...). They do not need to know about the channel or touch it.

Where you see it in this repo

  • Builder: BurgerMeal has private final fields; built only via the builder, no direct field access.
  • Singleton: JudgeAnalytics holds state in private fields, access via getters.
  • Observer: YouTubeChannel keeps its List<Subscriber> subscribers private; it notifies them internally.
  • Memento: EditorMemento has private final String content and only getContent().
  • SOLID: DIP/OCP/SRP examples use private fields and constructor or method parameters to pass dependencies and data.

In this topic

Done with this topic?

How well do you know it?

PreviousAbstract classes and inheritance