Skip to main content
Advertisement

7.5 Encapsulation & Access Modifiers

In Object-Oriented Programming, Encapsulation refers to the bundling of data (variables) and the methods that operate on that data into a single unit (a class). Crucially, it involves restricting direct access to some of an object's components, which is why it is often referred to as Information Hiding.

Just like a medical capsule hides the bitter medicine inside but provides an easy way to swallow it safely, encapsulation hides the complex code and vulnerable data, exposing only safe "buttons" for interaction. In Java, this is achieved using Access Modifiers.

1. Types of Access Modifiers

Access modifiers are keywords used before a class, method, or variable declaration to define its scope of visibility or accessibility. They are essential for security and maintaining data integrity. Java has four levels of access modifiers (ordered from most to least accessible):

ModifierAccessibility DescriptionVisibility Scope
publicNo restrictions. Can be accessed from anywhere in the program.Everywhere
protectedAccessible within the same package, AND by ** subclasses acting as children**in other packages.Package + Subclasses
(default)When no modifier is specified. Accessible only within the same package.Package only
privateAccessible ONLY within the class where it is declared. The most restrictive scope.Class only

Best Practice Tip: It is a strong industry standard to declare almost all instance variables (class state) as private to prevent direct external manipulation.

2. Implementing Encapsulation - Getters and Setters

If all data is marked private, how can other classes read or modify that data? The answer is to provide controlled, indirect access through methods declared as public. We call these methods Getters and Setters.

public class Person {
// 1. Completely hide all variables
private String name;
private int age;

// 2. Setter method for setting value (called from outside to update data)
public void setAge(int age) {
// We can add validation logic here!
if (age < 0 || age > 150) {
System.out.println("Error: Invalid age provided.");
return;
}
this.age = age;
}

// 3. Getter method for retrieving value (called from outside to read data)
public int getAge() {
return this.age;
}

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

// Getter
public String getName() {
return this.name;
}
}
public class EncapsulationExample {
public static void main(String[] args) {
Person p = new Person();

// p.age = -50; // COMPILER ERROR! Cannot access private field directly.
p.setAge(-50); // Using setter: Prints "Error: Invalid age provided."
p.setAge(25); // Valid data is stored successfully.

System.out.println("The person's age is: " + p.getAge());
}
}

Why Use Getters and Setters?

  1. Data Integrity (Validation): As shown with the age example, you can prevent invalid data (like -50 or conceptually impossible values) from polluting the object's state using if conditions within the setter.
  2. Creating Read-Only Properties: By providing only a Getter and removing the Setter, you can make a variable completely ** read-only**to the outside world.
  3. Hiding Internal Implementation: The outside world simply calls the public methods. If, in the future, the internal formula for calculating an age changes, the main program interacting with Person won't break. This promotes excellent maintainability.

Conclusion

We have now covered the four foundational pillars of Object-Oriented Programming (OOP): Inheritance, Polymorphism, Abstraction, and Encapsulation. While these concepts might initially feel theoretical or abstract, mastering them is an absolute prerequisite for advancing into Design Patterns and robust frameworks like Spring Boot in your Java journey.

Advertisement