Encapsulation In Java

In the object-oriented world, we have pillars of programming. One of them is Encapsulation the other three are Inheritance, polymorphism, and abstraction.
 
Here's the article which will explain, What, Why, and How of Encapsulation, and the other three are yet to be released one by one. So let’s get started with encapsulation.
 

Introduction

 
According to most of the resources, encapsulation means hiding the data members (variables and methods) within the class or a mechanism of wrapping/hiding a code and the variables/methods together as a unit.
 
In this, we will come across the entire concept of what encapsulation means, why to use encapsulation and how to achieve encapsulation in the programming world.
 

Data Hiding Vs Encapsulation

 
When encapsulation is implemented, only the variables inside the class can access it.
 
Therefore it's known as data hiding. But encapsulation and data hiding both are different from each other.
 
Data Hiding means protecting the members of a class from unauthorized/illegal access.
 
Encapsulation automatically achieves the concept of data hiding by providing security to data by making the variables as private.
 
As it is difficult to understand encapsulation through definitions we will learn in depth about this through some code examples,
  1. package Encapsulation;  
  2. //Use of POJO (Plain Old Java Object) class  
  3. public class Employee {  
  4.     //Member Variables  
  5.     String name;  
  6.     int age;  
  7.     String address;  
  8.     void code() {}  
  9.     void role() {}  
  10.     void employer() {}  
  11. }  
Here the common behavior and characteristics of an employee are enclosed in a single unit, the Employee.java class. This is a process of encapsulation.
 
An Employee object exposes its behavior and characteristics to the outside world.
  1. Employee emp = new Employee();  
  2. emp.name = "Aman";  
  3. emp.role();  
Here encapsulation hides implementation details of the Employee class. Similarly creating an interface is also a process of encapsulation.
  1. package Encapsulation;  
  2. interface Employee {  
  3.     void code();  
  4.     void role();  
  5.     void employer();  
  6. }  

How to achieve encapsulation?

  • Encapsulation is implemented in java using interfaces, class, access modifiers, setters, and getters.
  • A Class/Interface will encapsulate essential features of an object.
  • Access Modifiers such as private, public, protected restrict access to data at different levels.
  • Setter/Getter methods prevent data from misuse or unwanted changes.
For achieving encapsulation in java we declare the variable of a class as private. Private data members are used because they are only accessible within the class. It can’t be accessed using outside the class, the only way to access it is to use setter/getter methods.
 
Let’s modify the Employee. class to prevent the member variables name, age, and address from being modified by other objects.
  1. package Encapsulation;  
  2. //Use of POJO (Plain Old Java Object) class  
  3. public class Employee {  
  4.     private String name;  
  5.     private int age;  
  6.     private String address;  
  7. }  
Here’s the field name, age, and address that can be changed only in the Employee. class. If someone attempts to make a change like shown below, then code will not be compiled as the field is marked as private.
  1. Employee emp = new Employee();  
  2. emp.name = "Aman" ; //Compile Time Error  
But what if we want to modify/view the attributes values in a safer manner, then we use getter/setter methods. Creating a setter for field age,
  1. public void setAge(int age) {  
  2.     if (age < 18 || age > 58) {  
  3.         throw new IllegalArgumentException("Age must belong to 18 to 58 only");  
  4.     }  
  5.     this.age = age;  
  6. }  
Here, one can change the age of the Employee object and set it to a valid range. Likewise, with the name field associated with an Employee object, one can change the details but can’t enter null or empty values as the setter will throw an exception.
  1. public void setName(String name) {  
  2.     if (name.equals(null)) {  
  3.         throw new IllegalArgumentException("name cannot be null");  
  4.     }  
  5.     this.name = name;  
  6. }  
This protest data from unauthorized access or malicious changes, for example:
  1. Employee emp = new Employee();  
  2. emp.setName("");//IllegalArgumentException will be thrown  
  3. emp.setName("Aman");//Correct form  
So far we have learned what is encapsulation in java but the question arises of how to achieve encapsulation and the need to ensure encapsulation. Before moving forward to know how to achieve first we should know about what getter/ setter methods meant.
 
To get the code written in this article check here to my Github repository for the same.

Getter and Setter Methods

 
To ensure encapsulation, we make the data member variables of the class private. Now private members are only accessible within the class. It can’t be accessed outside the class as they restrict access to data.
 
So without much theory, we will start with some code as it's easy to understand what this means.
  1. package Encapsulation;  
  2. class Employee {  
  3.     private String name;  
  4.     private int age;  
  5.     private String address;  
  6.     public String getName() {  
  7.         return name;  
  8.     }  
  9.     public void setName(String name) {  
  10.         if (name.equals(null)) {  
  11.             throw new IllegalArgumentException("name cannot be null");  
  12.         }  
  13.         this.name = name;  
  14.     }  
  15.     public int getAge() {  
  16.         return age;  
  17.     }  
  18.     public void setAge(int age) {  
  19.         if (age < 18 || age > 58) {  
  20.             throw new IllegalArgumentException("Age must belong to 18 to 58 only");  
  21.         }  
  22.         this.age = age;  
  23.     }  
  24.     public String getAddress() {  
  25.         return address;  
  26.     }  
  27.     public void setAddress(String address) {  
  28.         if (address.equals(null)) {  
  29.             throw new IllegalArgumentException("Address cannot be null");  
  30.         }  
  31.         this.address = address;  
  32.     }  
  33.     // if not done will result in returning hashcode of the object  
  34.     @Override  
  35.     public String toString() {  
  36.         return "Employee [name=" + name + ", age=" + age + ", address=" + address + "]";  
  37.     }  
  38. }  
  39. public class employeeSet {  
  40.     public static void main(String[] args) {  
  41.         Employee emp = new Employee();  
  42.         emp.setName("Aman");  
  43.         emp.setAge(22);  
  44.         emp.setAddress("Meerut");  
  45.         //to print object details  
  46.         System.out.println(emp);  
  47.     }  
  48. }  
OUTPUT
 
Employee [name=Aman, age=22, address=Meerut] 

The above program has an Employee class with its three private member variables and their getters/setters respectively to understand the concept behind encapsulation and data hiding.
 

Why is encapsulation needed?

 
These are the reasons why we need encapsulation in everyday programming -- it increases the reusability and the flexibility of the code.
 
Some other reasons are mentioned below,
  • Objects encapsulate data and implementation details.
  • The functionality of the program is defined in one place.
  • Data inside our object is not modified unexpectedly by external code.
  • Encapsulation allows us to modify code without changing other code and controls how we access data.

Conclusion

 
So what we conclude from this article is summarized below.
 
Class is a base of encapsulation and is used to bind the data (variables) with its related functionalities (methods). With encapsulation, we can restrict access to critical data members which improves security.
 
We have hidden the data members (variables and methods) inside a class and have also specified the access modifiers so that they are not accessible to the outside world.
 

Summary

 
Thus, coming towards the end of this article, we had learned about encapsulation in Java.
 
What did we learn?
  • What is encapsulation?
  • Data Hiding Vs Encapsulation.
  • How to achieve encapsulation?
  • Getter and Setter Methods
  • Why is encapsulation needed?
To get the code written in this article check here to my GitHub repository for the same.
For other articles on design patterns,
  • Singleton Design Pattern here.
  • Factory Design Pattern here.
  • Builder Design Pattern here.
  • Bridge Design Pattern here.
  • Prototype Design Pattern here.
  • The static keyword here.