0/0
OOP Principles

Principles of OOP: Encapsulation

Wrap code and data into protected units — master information hiding via access modifiers, implementation hiding via interfaces, the "encapsulate what varies" design principle, and the crucial distinction between encapsulation and abstraction.

Explore Topics

🔒
Complete Encapsulation
Wrapping data and behavior into a single protected unit
🛡 Shield Builder — Progressive Encapsulation
0/5
⚠ VULNERABLE — No encapsulation layers active
Make Fields Private
Hide internal data from direct external access.
Data Visibility▶
Add Getters & Setters
Provide controlled access points to read/write data.
Controlled Access▶
Add Validation Logic
Enforce business rules inside methods — reject invalid state.
Invariant Protection▶
Defensive Copies
Prevent external mutation of mutable parameters and return values.
Reference Protection▶
Make Fully Immutable
Final class + final fields + no setters = maximum protection.
Total Immutability▶
🔒
Complete Encapsulation
Wrapping data and behavior into a single protected unit

Encapsulation is the bundling of data (fields) and the methods that operate on that data into a single unit (a class), while restricting direct access to internal state. A fully encapsulated class makes ALL fields private and provides controlled access through public methods. This is not just about adding getters and setters — it means the class controls its own invariants. For example, a BankAccount with deposit() and withdraw() methods can enforce "balance never goes negative," which a public field never could.

Key Ideas
  • Encapsulation = data + methods bundled together in one class
  • All fields private — no direct access from outside
  • Public methods provide controlled access with validation
  • The class enforces its own invariants (rules that must hold)
  • Fully encapsulated class: every field is private
  • No setBalance() — state changes only through meaningful operations
  • Encapsulation prevents invalid state (e.g., negative balance)
Strengths
  • ✦Protects data integrity — invalid state cannot be set from outside
  • ✦Simplifies debugging — state changes happen in one place
  • ✦Enables validation logic in methods (deposit checks amount > 0)
  • ✦Reduces coupling — clients depend on the interface, not the fields
Weaknesses
  • △Requires upfront design of the public API
  • △Can feel verbose for simple data-holder classes
  • △Over-encapsulation (unnecessary indirection) adds complexity
  • △Reflection can bypass private access (a known escape hatch)
Used in:java.lang.String is fully encapsulated — the internal char[]/byte[] array is private, and all operations go through methods like charAt(), substring(), and length().
Code Snippets

Quiz

Complete Encapsulation Quiz
QUIZ 1/6
class Counter {
    private int count = 0;
    public void increment() { count++; }
    public int getCount() { return count; }
}
Counter c = new Counter();
c.increment();
c.increment();
System.out.println(c.getCount());
What is the output of this code?

Diagrams

Encapsulation — Layers of Protection
Loading diagram...
Encapsulation vs Abstraction
Loading diagram...

Practice

Classify each technique: does it achieve Information Hiding, Implementation Hiding, or Both?
EXERCISE 1/6
Making fields private
Getters with validation
Returning interface types (List, Map)
Defensive copying in constructors
Strategy pattern
Declaring class final
Using access modifiers
Coding to an interface
Making objects immutable
Package-private helper classes
Information Hiding
Implementation Hiding
Both
Encapsulation Myths
EXERCISE 2/6
Adding getters and setters for every field is proper encapsulation.
A fully encapsulated class has all fields private.
Encapsulation and abstraction are the same thing.
Private fields can be accessed via Java reflection.
Immutable objects need synchronized access in multi-threaded code.
Protected members are only visible to subclasses.
Returning Collections.unmodifiableList() is a defensive copy.
A class with no public fields but a public setBalance() method that takes any value is well-encapsulated.
The Leaky Getter
EXERCISE 3/6
Click on the line you think contains the bug, then press Confirm.
1import java.util.*;
2
3class Course {
4 private List<String> students;
5
6 public Course(List<String> students) {
7 this.students = students;
8 }
9
10 public List<String> getStudents() {
11 return students;
12 }
13}
Defensive Copy Trace
EXERCISE 4/6
import java.util.*; final class Config { private final List<String> flags; Config(List<String> flags) { this.flags = List.copyOf(flags); } List<String> getFlags() { return flags; } } List<String> input = new ArrayList<>(List.of("debug")); Config cfg = new Config(input); input.add("verbose"); System.out.println(cfg.getFlags().size()); System.out.println(input.size());
cfg.getFlags().size()
input.size()
Build an Immutable Class
EXERCISE 5/6
class Temperature { final double celsius; public Temperature(double celsius) { this.celsius = celsius; } public double getCelsius() { return celsius; } public double toFahrenheit() { return celsius * 9.0 / 5.0 + 32; } public Temperature add(double delta) { return ; } }
Encapsulate a Class — Step by Step
EXERCISE 6/6
Drag the lines into the correct order.
class Person {
private String name;
private int age;
public Person(String name, int age) {
if (age < 0) throw new IllegalArgumentException();
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
}

References

📋

Oracle Java Tutorials — Controlling Access to Members of a Class

docs.oracle.com

docs
📚

Effective Java, 3rd Edition — Items 15-17: Minimize Accessibility & Mutability (Joshua Bloch)

oreilly.com

book
📄

Baeldung — Encapsulation in Java

baeldung.com

article
📚

Head First Design Patterns, 2nd Edition — "Encapsulate What Varies" (Freeman & Robson)

oreilly.com

book
📄

Parnas (1972) — On the Criteria To Be Used in Decomposing Systems into Modules

win.tue.nl

article