Encapsulation in Java¶
Overview¶
Encapsulation is a fundamental concept of Object-Oriented Programming (OOP).
It describes the practice of restricting direct access to an object's internal data and allowing interaction only through controlled methods.
In Java, encapsulation is mainly implemented using:
privatefieldspublicmethods (e.g., getters, setters, business methods)- constructors for controlled initialization
The goal is to protect data, simplify interfaces, and reduce coupling between classes.
Core Concept¶
Encapsulation separates a class into two conceptual parts:
| Part | Description |
|---|---|
| Public Interface | Methods accessible from outside the class |
| Internal Implementation | Private fields and internal logic hidden from other classes |
Only the public interface should be visible to other classes.
External Code
│
▼
Public Methods (Interface)
│
▼
Private Data + Internal Logic
This turns a class into a black box:
Other classes can use it, but they cannot manipulate its internal state directly.
Why Encapsulation Is Important¶
Encapsulation solves several design problems.
1. Protecting Data Integrity¶
If fields are public, external code can change them arbitrarily.
Example problem:
player.health = 200; // invalid state
This bypasses the logic that should ensure:
health must stay between 1 and 100
Encapsulation ensures that all modifications pass through controlled methods.
2. Preventing Logic Bypass¶
Business rules are often implemented inside methods.
Example:
restoreHealth(int amount)
This method may contain logic such as:
- max health = 100
- health cannot exceed limits
If fields are public, code can skip these rules entirely.
3. Reducing Coupling¶
When fields are public, external code depends on internal implementation details.
Example:
player.name
If the field is renamed to:
fullName
All calling code breaks.
Encapsulation avoids this because external code calls:
player.getName();
Internal changes do not affect external classes.
4. Ensuring Valid Object Initialization¶
Without encapsulation, objects may be created in an invalid state.
Example:
Player player = new Player();
Fields may remain uninitialized:
health = 0
name = null
Using constructors allows enforcing valid object creation.
Example Without Encapsulation¶
Class Design¶
Fields are public and can be modified directly.
public class Player {
public String name;
public int health;
public String weapon;
public void loseHealth(int damage) {
health = health - damage;
if (health <= 0) {
System.out.println("Player knocked out of the game");
}
}
public int healthRemaining() {
return health;
}
public void restoreHealth(int extraHealth) {
health = health + extraHealth;
if (health > 100) {
System.out.println("Player restored to full health");
health = 100;
}
}
}
Problems¶
- Fields are directly accessible
- External code can bypass validation
- Internal changes break external code
- Object initialization is not guaranteed
Example misuse:
player.health = 200;
Encapsulated Class Design¶
The improved design hides internal fields.
public class EnhancedPlayer {
private String name;
private int health;
private String weapon;
public EnhancedPlayer(String name, int health, String weapon) {
this.name = name;
this.weapon = weapon;
if (health <= 0) {
this.health = 1;
} else if (health > 100) {
this.health = 100;
} else {
this.health = health;
}
}
public EnhancedPlayer(String name) {
this(name, 100, "Sword");
}
public void loseHealth(int damage) {
health = health - damage;
if (health <= 0) {
System.out.println("Player knocked out of the game");
}
}
public int healthRemaining() {
return health;
}
public void restoreHealth(int extraHealth) {
health = health + extraHealth;
if (health > 100) {
System.out.println("Player restored to full health");
health = 100;
}
}
}
Constructor Chaining¶
The second constructor calls the first.
public EnhancedPlayer(String name) {
this(name, 100, "Sword");
}
Benefits:
- default values
- simpler object creation
- guaranteed initialization
Example usage:
EnhancedPlayer player = new EnhancedPlayer("Tim");
Result:
name = "Tim"
health = 100
weapon = "Sword"
Encapsulation Structure¶
classDiagram
class EnhancedPlayer {
- String name
- int health
- String weapon
+ EnhancedPlayer(String name, int health, String weapon)
+ EnhancedPlayer(String name)
+ loseHealth(int damage)
+ restoreHealth(int amount)
+ healthRemaining()
}
Legend:
-private members+public methods
Benefits of Encapsulation¶
| Benefit | Explanation |
|---|---|
| Data protection | Prevents uncontrolled modification |
| Validation | Enforces rules before changing data |
| Flexibility | Internal implementation can change |
| Reduced coupling | External classes depend only on public methods |
| Safer initialization | Constructors guarantee valid objects |
Access Modifiers and Encapsulation¶
| Modifier | Visibility | Typical Use |
|---|---|---|
private |
Only inside the class | Fields, helper methods |
protected |
Class + subclasses | Carefully used in inheritance |
public |
Everywhere | Public API methods |
Best practice:
fields → private
methods → public only if needed
Practical Example¶
Game logic:
EnhancedPlayer tim = new EnhancedPlayer("Tim", 200, "Sword");
System.out.println(tim.healthRemaining());
Even though 200 is passed:
health = 100
because the constructor enforces the rule.
Exam Relevance (FIAE)¶
Typical exam questions include:
- Explain encapsulation in OOP
- Identify problems of public fields
- Explain the purpose of private fields
- Explain how constructors support encapsulation
- Understand API vs internal implementation
Important keyword definition:
Encapsulation is the bundling of data and methods in a class while restricting direct access to the internal state of the object.
Common Mistakes¶
1. Making fields public¶
public int health;
This breaks encapsulation.
Correct:
private int health;
2. Adding unnecessary setters¶
Not every field needs a setter.
Example:
health should only change via game logic
3. Forgetting validation¶
Constructors and setters should enforce constraints.
Example rule:
health ∈ [1,100]
4. Confusing "interface"¶
Two meanings exist:
| Term | Meaning |
|---|---|
Java interface |
Special Java type |
| Class interface | Public methods available to other classes |
In encapsulation, interface means the public API of a class.
Key Takeaway¶
Encapsulation makes classes behave like self-contained modules.
Rules:
- Fields should usually be private
- Provide controlled access via methods
- Use constructors to ensure valid objects
- Hide internal implementation details
Well-encapsulated classes are easier to maintain, safer, and more flexible to change.