Chapter[13]: Understanding Encapsulation: A Beginner’s Guide
When designing a class, such as Person
, not every detail should be directly accessible or editable. Imagine if someone could set your age to -5 or change your name to "12345" without any checks—chaos! This is where encapsulation steps in to save the day.
So What Exactly is Encapsulation?
Encapsulation is the practice of bundling data (attributes) and methods (actions) that operate on that data into a single unit. It restricts direct access to some of the object’s components by making them private or protected. Why? Because not every detail of an object should be open to the world. It’s like locking your valuables in a safe — only trusted individuals (or methods) get the key, ensuring control and security.
For instance:
- Some attributes might be sensitive (like a password, social security number, or aadhar card number) and shouldn’t be directly accessible.
- Others might need validation before modification (like ensuring a person’s age isn’t negative).
Here’s how it looks in code:
Example 1: Sensitive Data Protection
class BankAccount {
private String accountNumber; // Sensitive information, private for security
public BankAccount(String accountNumber) {
this.accountNumber = accountNumber;
}
// Only a getter to allow read-only access
public String getAccountNumber() {
return "****" + accountNumber.substring(accountNumber.length() - 4); // Masked output
}
}
Why? The accountNumber
is private to prevent unauthorized access. The public getter returns only the last 4 digits to protect sensitive data.
Example 2: Validation Before Modification
class Person {
private int age; // Restrict direct access to ensure valid values
public void setAge(int age) {
if (age > 0) {
this.age = age;
} else {
throw new IllegalArgumentException("Age must be positive!");
}
}
public int getAge() {
return age;
}
}
Why? Directly setting the age
attribute without checks could allow invalid values (e.g., age = -5
). By restricting direct access and using a setter, we ensure data integrity.
Why Do We Need Encapsulation?
Encapsulation is more than just hiding data. It serves multiple essential purposes:
- Data Security: Sensitive data is hidden, minimizing the risk of accidental corruption or unauthorized access.
- Controlled Access: Clear rules for reading and modifying data ensure its integrity.
- Flexibility: Internal details can evolve without affecting external code.
- Reusability: Modular classes with well-defined interfaces can be extended or reused.
Encapsulation enforces the principle of controlling access to the internals of an object while exposing only what’s necessary for external use.
How Encapsulation Works
Encapsulation operates on three key principles:
- Private Attributes: Hide the internal state of the object by declaring attributes as private.
- Public Methods: Provide controlled access to private attributes through public getter and setter methods.
- Class Bundling: Combine related attributes and methods into a single cohesive unit, the class.
Here’s a visual representation of a Person
class:
-----------------------------------------------
| Attributes: |
| - private name : String |
| - private age : int |
| - private gender : String |
|---------------------------------------------|
| Public Methods: |
| + speak() : void |
| + getName() : String |
| + setName(name: String) : void |
| + getAge() : int |
| + setAge(age: int) : void |
| + getGender() : String |
| + setGender(gender: String) : void |
-----------------------------------------------
Encapsulation in Action
Step 1: Define the Class
We create a Person
class with private attributes and public methods to access or modify them.
class Person {
private String name; // Keep private to control access
private int age; // Private to validate changes
private String gender; // Private to protect integrity
// Constructor
public Person(String name, int age, String gender) {
this.name = name;
setAge(age); // Use setter for validation
this.gender = gender;
}
// Public getter for name
public String getName() {
return name;
}
// Public setter for name with checks
public void setName(String name) {
if (name != null && !name.isEmpty()) {
this.name = name;
} else {
throw new IllegalArgumentException("Name cannot be empty");
}
}
// Public getter for age
public int getAge() {
return age;
}
// Public setter for age with validation
public void setAge(int age) {
if (age > 0) {
this.age = age;
} else {
throw new IllegalArgumentException("Age must be positive");
}
}
public void speak() {
System.out.println("Hi, I am " + name + ", a " + age + "-year-old " + gender + ".");
}
}
Step 2: Extend the Class
Create specific roles like Student
and Driver
by extending the Person
class.
class Student extends Person {
private String grade;
public Student(String name, int age, String gender, String grade) {
super(name, age, gender); // Call the Person constructor
this.grade = grade;
}
public void study() {
System.out.println(getName() + " is studying in grade " + grade + ".");
}
}
class Driver extends Person {
private String licenseType;
public Driver(String name, int age, String gender, String licenseType) {
super(name, age, gender);
this.licenseType = licenseType;
}
public void drive() {
System.out.println(getName() + " is driving with a " + licenseType + " license.");
}
}
Step 3: Demonstrate Encapsulation
public class EncapsulationDemo {
public static void main(String[] args) {
Student student = new Student("Alice", 15, "Female", "10th Grade");
student.speak();
student.study();
Driver driver = new Driver("Bob", 35, "Male", "Commercial");
driver.speak();
driver.drive();
driver.setName("Robert");
System.out.println("Updated Name: " + driver.getName());
}
}
Output:
Hi, I am Alice, a 15-year-old Female.
Alice is studying in grade 10th Grade.
Hi, I am Bob, a 35-year-old Male.
Bob is driving with a Commercial license.
Updated Name: Robert
Benefits of Encapsulation
- Controlled Access: Attributes like
name
,age
, andgender
are protected by making them private. - Data Integrity: Validation logic in setters ensures valid values.
- Abstraction: Other classes interact only through the public interface.
Encapsulation ensures your code is secure, modular, and adaptable — a must-have for modern software design.
check and download the sample code here.
You can now catch the podcast on YouTube too!
.
.
.
Happy Coding!