Lesson 40 of 50 – Java Encapsulation
80%

Java Encapsulation

Encapsulation is one of the four main principles of Object-Oriented Programming (OOP). It means combining data and the methods that operate on that data inside a class while controlling access to the internal state.

1. What Is Encapsulation?

Encapsulation is the process of wrapping variables and methods together in a class and restricting direct access to internal data when appropriate.

In Java, encapsulation is commonly achieved by:

  • Declaring fields as private.
  • Providing public methods to read or update fields.
  • Validating data before changing an object's state.
class Student {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

class Main {
    public static void main(String[] args) {
        Student s1 = new Student();

        s1.setName("Rahul");

        System.out.println(s1.getName());
    }
}
Output:
Rahul
2. Why Do We Need Encapsulation?
  • To protect internal data from uncontrolled changes.
  • To validate values before storing them.
  • To make classes easier to maintain.
  • To control how other classes access an object's data.
  • To reduce unwanted dependencies between classes.
Example: A bank account should not allow anyone to directly change its balance to an invalid value. Encapsulation helps control balance updates.
3. Private Variables

The private access modifier restricts access to a field or method to within the class where it is declared.

class Employee {
    private int salary = 25000;

    public void showSalary() {
        System.out.println(salary);
    }
}

class Main {
    public static void main(String[] args) {
        Employee e1 = new Employee();

        e1.showSalary();

        // This would cause a compilation error:
        // System.out.println(e1.salary);
    }
}
Output:
25000

The salary field cannot be accessed directly from the Main class because it is private.

4. Getter Methods

A getter is a method used to read the value of a field.

class Student {
    private String name = "Amit";

    public String getName() {
        return name;
    }
}

class Main {
    public static void main(String[] args) {
        Student s1 = new Student();

        System.out.println(s1.getName());
    }
}
Output:
Amit

The getName() method provides controlled access to the private name field.

5. Setter Methods

A setter is a method used to update a field's value.

class Student {
    private int age;

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }
}

class Main {
    public static void main(String[] args) {
        Student s1 = new Student();

        s1.setAge(20);

        System.out.println(s1.getAge());
    }
}
Output:
20

The setter updates the private field, and the getter returns its current value.

6. Using this Keyword in Encapsulation

The this keyword refers to the current object. It is often used when a parameter has the same name as a field.

class Student {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

class Main {
    public static void main(String[] args) {
        Student s1 = new Student();

        s1.setName("Priya");

        System.out.println(s1.getName());
    }
}
Output:
Priya

this.name refers to the object's field, while name refers to the method parameter.

7. Data Validation with Setters

A setter can validate input before storing it. This prevents invalid values from being accepted through that method.

class Student {
    private int age;

    public void setAge(int age) {
        if (age >= 1 && age <= 100) {
            this.age = age;
        } else {
            System.out.println("Invalid age");
        }
    }

    public int getAge() {
        return age;
    }
}

class Main {
    public static void main(String[] args) {
        Student s1 = new Student();

        s1.setAge(20);
        System.out.println(s1.getAge());

        s1.setAge(-5);
    }
}
Output:
20
Invalid age

The setter accepts ages from 1 to 100 and rejects values outside that range.

8. Complete Encapsulation Example
class Employee {
    private String name;
    private double salary;

    public void setName(String name) {
        if (name != null && !name.isBlank()) {
            this.name = name;
        }
    }

    public String getName() {
        return name;
    }

    public void setSalary(double salary) {
        if (salary >= 0) {
            this.salary = salary;
        } else {
            System.out.println("Salary cannot be negative");
        }
    }

    public double getSalary() {
        return salary;
    }
}

class Main {
    public static void main(String[] args) {
        Employee e1 = new Employee();

        e1.setName("Ravi");
        e1.setSalary(30000);

        System.out.println("Name: " + e1.getName());
        System.out.println("Salary: " + e1.getSalary());

        e1.setSalary(-5000);
    }
}
Output:
Name: Ravi
Salary: 30000.0
Salary cannot be negative

This example uses private fields, public getters, public setters, and validation rules. String.isBlank() is available in Java 11 and later.

9. Encapsulation in a Bank Account
class BankAccount {
    private double balance;

    public BankAccount(double initialBalance) {
        if (initialBalance >= 0) {
            balance = initialBalance;
        } else {
            throw new IllegalArgumentException(
                "Initial balance cannot be negative"
            );
        }
    }

    public double getBalance() {
        return balance;
    }

    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        } else {
            System.out.println("Invalid deposit amount");
        }
    }

    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
        } else {
            System.out.println("Invalid withdrawal amount");
        }
    }
}

class Main {
    public static void main(String[] args) {
        BankAccount account = new BankAccount(1000);

        account.deposit(500);
        account.withdraw(200);

        System.out.println(
            "Balance: " + account.getBalance()
        );
    }
}
Output:
Balance: 1300.0

The balance is private. Deposits and withdrawals are performed through methods that validate amounts.

10. Access Modifiers and Encapsulation
Modifier Accessibility
private Within the declaring class
No modifier (package-private) Within the same package
protected Within the same package and, subject to Java's inheritance access rules, in subclasses
public Accessible wherever the declaring type and its members are accessible
A common encapsulation pattern is to make fields private and expose only the operations that callers actually need. Not every field requires a setter.
11. Advantages of Encapsulation
  • Protects an object's internal state from direct access.
  • Allows validation before accepting new values.
  • Makes implementation changes easier to manage.
  • Provides clear methods for interacting with an object.
  • Helps keep an object in a valid state.
Important Limitation

Encapsulation does not automatically make a program secure. The methods exposed by a class must also be designed with appropriate validation and access control.

12. Encapsulation vs Abstraction
Encapsulation Abstraction
Controls access to an object's internal state. Hides implementation details and exposes essential behavior.
Often uses private fields and public methods. Often uses interfaces and abstract classes.
Example: A private bank balance with deposit and withdraw methods. Example: A Payment interface with a pay method.
Both concepts help create maintainable programs, but they solve different design problems.
13. Practice Assignments
  1. Create a Student class with private name and age fields and public getter and setter methods.
  2. Create an Employee class with a private salary field. Reject negative salary values.
  3. Create a BankAccount class with a private balance, deposit(), withdraw(), and getBalance() methods.
  4. Create a Product class with private price and quantity fields. Validate values using setters.
  5. Create a Person class with private name and email fields and methods to read and update them.
  6. Create a Rectangle class with private length and width fields and a method to calculate area.
  7. Explain the difference between encapsulation and abstraction with examples.
Practice Tip: Try making every field private first. Then add only the methods needed to safely use the object.

🧠 Quick Quiz

1. What is encapsulation?




2. Which access modifier commonly protects fields in an encapsulated class?




3. What is the main purpose of a setter method?