Encapsulation in Java

One of the four pillars of the OOP concept is encapsulation. Inheritance, polymorphism, and abstraction are the other three.

In Java, encapsulation combines data (variables) and code that acts on the data (methods) into a single unit. Encapsulation means that a class’s variables are concealed from other classes and can only be accessed through its current class’s methods. Consequently, it’s also known as data concealment.

The goal of encapsulation is to keep implementation details hidden from users. Other members of the same class can only access a private data member. No outside class has access to a class’s private data member (variable).

However, suppose we create public getter and setter methods to update (for example, void setEmployee(int ID)) and read (for example, int getEmployee()) the private data fields. In that case, the outside class can use those public methods to access those private data fields. Private fields and their implementation are hidden from outside classes since public methods can only access data.

Encapsulation in Java

To implement encapsulation in Java,

  • Declare a class’s variables as private.
  • To alter and inspect the variables’ values, provide public setter and getter methods.

Following that, we’ll look at the syntax you use when implementing encapsulation in Java.The syntax is as follows:

<Access_Modifier> class <Class_Name> {

 private <Data_Members>;

 private <Data_Methods>;

}

Let’s explore the sample program below to understand the encapsulation process better.

Example: The following code illustrates how to implement Encapsulation in Java.

/* File name : CodeEncapsulation.java */

public class CodeEncapsulation {

   private String name;
   private String idNum;
   private int age;

   public int getAge() {
      return age;
   }

   public String getName() {
      return name;
   }

   public String getIdNum() {
      return idNum;
   }

   public void setAge( int newAge) {
      age = newAge;
   }

   public void setName(String newName) {
      name = newName;
   }

   public void setIdNum( String newId) {
      idNum = newId;
   }
}

The public setXXX() and getXXX() methods provide access to the CodeEncapsulation class’s instance variables. These methods collectively are commonly referred to as getters and setters. As a result, any class that needs access to the variables should use these getters and setters. The CodeEncapsulation class variables are accessed with the following program:

/* Filename : RunCodeEncapsulation.java */
public class RunCodeEncapsulation {

   public static void main(String args[]) {
      CodeEncapsulation encapVar = new CodeEncapsulation();
      encapVar.setName("Green");
      encapVar.setAge(53);
      encapVar.setIdNum("TY905");

      System.out.print("Name : " + encapVar.getName() + " Age : " + encapVar.getAge());
   }
}

Methods of Getter and Setter

Getter

A getter method is a method that allows you to access and retrieve an instance of a private variable.

Setter

The setter method is capable of updating or setting a private variable instance.

package Codeunderscored;

public class CodeEmployee {

private String c_name;

public String getCodeName() {

return c_name;

}

public void setCodeName(String c_name){  

this.c_name=c_name ;

}

}

package Codeunderscored;

public class CodeTestGettersSetters {

public static void main(String[] args) {

CodeEmployee empOne = new CodeEmployee();

empOne.setCodeName("Green");

System.out.println(empOne.getCodeName());

}

}

//Output: Green

Encapsulation’s Advantages

  • You can make a class read-only or write-only by giving only a setter or getter method.
  • In other words, the getter and setter methods are optional.
  • The most common IDEs provide the ability to generate getters and setters. Creating an enclosed class in Java is thus simple and quick. By extension, this eases the entire process of writing programs.
  • Encapsulation in Java allows you to reuse your code.
  • Encapsulation allows you to make modifications to existing code swiftly.
  • It gives you complete control over your data. You can write the logic inside the setter method if you only want to set the value of id to be greater than 100. You can implement logic in the setter methods to prevent negative integers from being stored.
  • A class can have complete control over the content of its fields.
  • Because other classes will not be able to access the data through the private data members, it is a way to achieve data hiding in Java. It’s simple to test the enclosed class. As a result, it is more suitable for unit testing.
  • Unit testing code written with encapsulation is simple.

Encapsulation in Java: A Simple Example

Let’s look at a simple encapsulation example with only one field and setter and getter methods.

// A Java class that is completely enclosed. It has a getter and setter method and a private data member.

package com.codeunderscored;  

public class CodeStudent{  

  //the data member  is  private
  private String name;  

  // name's getter method
  public String getName(){  
    return name;  
  }  
  //names' setter method
  public void setName(String name){  
    this.name=name  
    }  
}  


//The Java class here tests the encapsulated class above
package com.codeunderscored;  

class CodeTest{  

  public static void main(String[] args){  

    //first, create an instance of the encapsulated class  

    CodeStudent codeStudent = new CodeStudent();  

    // using the setter method to assign value to the name member  
    codeStudent.setName("Green");  

    // Using the name's get method to fetch the value of the name member  
    System.out.println(codeStudent.getName());  
  }  
}  

The following is a read-only class.

//Only getter methods are available in this Java class.

public class CodeStudent{  

  //The data member is  private
  private String code_school="Code Underscored";  

  // code_school's getter method
  public String getCodeSchool(){  
    return code_school;  
  }  
}

You can no longer edit the value of the code_school data member “Code Underscored .”

codeStudent.setCodeSchool("w3schools");// the code renders a compile time error

The following is a write-only class:

//Only setter methods are available in this Java class.
public class CodeStudent{  

  //data member  is private
  private String code_school;  

  //code_school's setter method
  public void setCodeSchool(String code_school){  
    this.code_school=code_school;  
  }  
}  

You can no longer access the code_school’s value; instead, you can only update the value of the code_school data component.

System.out.println(codeStudent.getCodeSchool());//There is no such procedure, resulting in a Compile Time Error.
System.out.println(codeStudent.code_school);//Because the college data member is private, there is a Compile Time Error.
//As a result, it is not accessible from outside the class.

Another Java example of encapsulation

Let’s look at another encapsulation example with only four fields and setter and getter functions.

//   An Account class that is completely contained.
// It has a getter and setter method and a private data member.

class CodeAccount {  

  //The data members are private

  private long code_acc_no;  
  private String code_name,code_email;  
  private float code_amount;  

  //These getter and setter methods  are all public
  public long getCodeAccNo() {  
    return code_acc_no;  
  }  
  public void setCodeAccNo(long code_acc_no) {  
    this.code_acc_no = code_acc_no;  
  }  
  public String getCodeName() {  
    return code_name;  
  }  
  public void setCodeName(String code_name) {  
    this.code_name = code_name;  
  }  
  public String getCodeEmail() {  
    return code_email;  
  }  
  public void setCodeEmail(String code_email) {  
    this.code_email = code_email;  
  }  
  public float getCodeAmount() {  
    return code_amount;  
  }  
  public void setCodeAmount(float code_amount) {  
    this.code_amount = code_amount;  
  }  

}  




//A Java class for testing the encapsulated Account class.

public class CodeTestEncapsulation {  

  public static void main(String[] args) {  

    //creation of CodeAccount class instance
    CodeAccount codeAccount=new CodeAccount();  

    //Using the setter methods to set values
    codeAccount.setCodeAccNo(111THY78645);  
    codeAccount.setCodeName("Code Underscored");  
    codeAccount.setCodeEmail("code@codeunderscored.com");  
    codeAccount.setCodeAmount(250f);  

    // using the getter methods to fetch respective  values
    System.out.println(codeAccount.getCodeAccNo()+" "+codeAccount.getCodeName()+" "+codeAccount.getCodeEmail()+" "+codeAccount.getCodeAmount());  
  }  
}  

Example: Encapsulation in Java

class CodeArea {

  // fields for calculating the area
  int c_length;
  int c_breadth;

  // constructor for values initialization

  CodeArea(int c_length, int c_breadth) {
    this.c_length = c_length;
    this.c_breadth = c_breadth;
  }

  // method responsible for area calculate
  public void getCodeArea() {
    int resultantArea = c_length * c_breadth;
    System.out.println("Resultant Area is: " + resultantArea);
  }
}

class Main {
  public static void main(String[] args) {

    // create object of Area
    // pass value of length and breadth
    resultantArea rec = new resultantArea(12, 16);
    rec.getCodeArea();
  }
}

We established a class called CodeArea in the previous example. The class’s primary goal is to compute the area. Two variables, c_length, and c_breadth, plus a method, getCodeArea, are required to determine the area. As a result, we combined these attributes and methods into one class.

The properties and methods of this class can also be accessible from other classes. As a result, this is not data concealment. It is only a summary. We’re just grouping comparable codes. While many people think of encapsulation as data hiding, this is not totally accurate. Encapsulation is the grouping together of similar fields and procedures. You can use it to conceal information. Data hiding is, therefore, not the same as encapsulation.

What is the purpose of encapsulation?

Encapsulation in Java allows us to group relevant fields and methods, making our code clearer and easier to read.

It aids in the management of our data fields’ values. For instance,

class CodeEmployee {
  private int age;

  public void setCodeAge(int c_age) {
    if (age >= 0) {
      this.c_age = c_age;
    }
  }
}

The c_age variable is now private, and logic is applied inside the setCodeAge() method. c_age is no longer a negative factor. Our class fields can exist as read-only or write-only. The latter is dependent on either using the getter and setter methods. For instance,

getCodeName()  // provides access for read-only
setCodeName() // provides access for write-only

It aids in the decoupling of system components. We can, for example, divide code into multiple bundles. These detached components (bundle) can be built, tested, and debugged on their own time. Furthermore, any changes made to one component have no impact on the others. Encapsulation can also be used to conceal data. If we set the length and breadth variables to private in the previous example, access to these fields is restricted. They are also kept secret from the upper classes. It is referred to as data concealment.

Hiding Data

Data hiding is a method of limiting data members’ access to our data by concealing implementation details. Encapsulation also allows data to be hidden. You can hide data by using access modifiers.

The following are the four access specifiers:

Default

The first line of data concealing is the default. In case no access specifier is explicitly specified for a given Java class, the compiler will use ‘default’ as the access specifier. The default access specifier is very similar to the public access specifier in terms of functionality.

Public

The least restrictive access modifier is this. Methods and properties with the public modifier can be accessible both within and outside of your current class.

The public API of your class and any component you include includes public methods and attributes. It is usually never a good idea for any attribute. Therefore use caution when applying this modification to a method. When a method is made publicly available, it must be adequately described and capable of handling input values. Remember that this technique will be utilized by a portion of your program, making it difficult to update or eliminate.

Your public API should, in general, be as light as feasible. Only the methods used by other portions of the program or external clients are included in public APIs. The public access specifier gives class access to its access specifications for access from anywhere in the program.

Example:

package Codeunderscored;

class CodeVehicle {

public int c_tires;

public void CodeDisplay() {

System.out.println("Codeunderscored owns a vehicle.");

System.out.println("The vehicle has " + c_tires + " number of wheels.");

}

}

public class CodeTestVehicle {

public static void main(String[] args) {

CodeVehicle codeVehicle = new CodeVehicle();

codeVehicle.tires = 8;

codeVehicle.display();

}

}

//Output: Codeunderscored owns a vehicle.
// It has 8 number of wheels.

Private

The private modifier, the most restrictive and widely used access modifier, restricts access to an attribute or method to other members of the same class. This attribute or method is not accessible to subclasses or other classes in the same or different package.

By default, choose the private modifier for all attributes and internal methods you should not call from outside classes. You may need to make an exception to this rule when using inheritance. Also, some subclasses that require direct access to a property or internal method should be exempted. Instead of using the private modifier, you should use the protected modifier. The data members use the private access specifier for accessibility. On the other hand, the data methods are limited to the class itself.

Example:

package Codeunderscored;

class CodeEmployee {

private int code_rank;

public int getCodeRank() {

return code_rank;

}

public void setCodeRank(int code_rank) {

this.code_rank = code_rank;

}

}

public class CodeTestEmployee {

public static void main(String[] args) {

CodeEmployee codeEmployee = new CodeEmployee();

codeEmployee.setCodeRank(1);

System.out.println("The Code Employee's rank is " + codeEmployee.getCodeRank());

}

}

// Output:
// The Code Employee's rank is 1

Protected

Like the private access specifier, the protected access specifier safeguards the class methods and members. The main distinction is that instead of restricting access to a single class, the package as a whole is restricted. Internal methods that must be called or overridden by subclasses are usually given the protected modifier. You can also use the protected modifier to give subclasses direct access to a superclass’s internal attributes.

package Codeunderscored;

class Computer {

protected String code_stream;

protected void CodeDisplay() {

System.out.println("Hello, people refer to me as the " + code_stream + " Technology");

}

}

public class SuperComputer extends Computer {

public static void main(String[] args) {

SuperComputer superComputer = new SuperComputer();

superComputer.stream = " super computer  because of my ";

SuperComputer.CodeDisplay();

}

}

//Output:
// Hello, people refer to me as the  super computer  because of my Technology

Example: Data hiding

class CodeEmployee {

  // private field
  private int c_age;

  // getter method
  public int getCodeAge() {
    return c_age;
  }

  // setter method
  public void setCodeAge(int c_age) {
    this.c_age = c_age;
  }
}

class Main {
  public static void main(String[] args) {

    // creating a Person's Object
    CodeEmployee empOne = new CodeEmployee();

    // using the setter method to change the  c_age
    empOne.setCodeAge(32);

    // using the getter method to access c_age
    System.out.println("My Current age is :" + empOne.getCodeAge());
  }
}

We have a private field c_age in the example above. You cannot access it from outside the class because it’s private. In this example, we utilized the public methods getCodeAge() and setCodeAge() to retrieve c_age. These are known as getter and setter methods. We were able to prohibit illegal access from outside the class by making age secret. This is data concealment. Attempts to access the c_age field from the Main class will get an error.

// error: c_age has private access in CodeEmployee
empOne.c_age = 36;

Encapsulation vs. Abstraction

Abstraction and encapsulation are frequently confused. Let us investigate-

  • Encapsulation is mainly concerned with the “How” of achieving functionality.
  •  
  • Abstraction is primarily concerned with “What” a class can accomplish.

A mobile phone is an easy way to understand the difference where the circuit board’s sophisticated circuitry is encapsulated in a touch screen, with an interface to abstract it away.

Example: Program for demonstrating variable access using encapsulation in Java

class CodeEncapsulate {

	// The following private variables declared below can only be accessed by the class's public methods

	private String codeName;
	private int codeRoll;
	private int codeAge;

	// getting the method for age to access
	// private variable codeAge
	public int getCodeAge() { return codeAge; }

	// getting the method for name to access
	// private variable codeName
	public String getName() { return codeName; }

	// getting the method for roll to access
	// private variable codeRoll
	public int getCodeRoll() { return codeRoll; }

	// setting the method for age to access
	// private variable codeAge
	public void setCodeAge(int codeAge) { codeAge = codeAge; }

	// setting the method for codeName to access
	// private variable codeName
	public void setCodeName(String codeName)
	{
		codeName = codeName;
	}

	// set method for roll to access
	// private variable geekRoll
	public void setRoll(int newRoll) { geekRoll = newRoll; }
}

public class TestCodeEncapsulation {
	public static void main(String[] args)
	{
		CodeEncapsulate codeEncapsulate = new CodeEncapsulate();

		// setting values of the variables
		codeEncapsulate.setCodeName("Green");
		codeEncapsulate.setCodeAge(34);
		codeEncapsulate.setCodeRoll(198);

		// Displaying the variable values
		System.out.println("Code's name: " + codeEncapsulate.getCodeName());
		System.out.println("Code's age: " + codeEncapsulate.getAge());
		System.out.println("Code's roll: " + codeEncapsulate.getRoll());

		// Direct access of CodeRoll is not possible because of encapsulation
		// System.out.println("Code's roll: " +// codeEncapsulate.CodeName);
	}
}

Conclusion

In Java, encapsulation combines code and data into a single unit, such as a capsule containing several drugs. Further, in Java, we can create a fully enclosed class by keeping all of the class’s data members private. We can now set and get data using setter and getter methods. The Java Bean class represents a fully contained class. It’s frequently used to implement a data-hiding method. This strategy minimizes the accessibility of properties to the current class and controls and restricts external access to these attributes using public getter and setter methods. These methods let you specify which characteristics can be read or updated and validate the new value before making a change.

Encapsulation has the basic property of hiding data and ensuring the security of user data. Encapsulation is a good OOP practice. However, it works best when combined with a reliable APM solution like Retrace for error monitoring.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *