Encapsulation Overview

Encapsulation in Java

The literal meaning of the term 'Encapsulation' is encasing like a capsule where data and methods work together as a single unit. It's one of the four pillars of Object orientated programming. We will talk about the other three at later stages.

Here, we will talk about Why we need Encapsulation in the first place and how exactly we achieve it. We will also explore in this, what are setters and getters along with an intro to constructors.

Why do we need Encapsulation?

Encapsulation is needed, so that we can prevent objects of one class from being able to directly access the data of another class or you can say it is done in order to not expose the data to other classes/objects.

We also use it to control access and set limitations. We will see in this article how exactly we achieve this.

What is Encapsulation?

Encapsulation = Data hiding + Data Abstraction.

  1. Data hiding means not exposing the data of a class to any other class or object of a class.

  2. Data abstraction means not exposing what actions are being performed on those data.

How do we achieve it?

We achieve encapsulation using the Keyword 'private' before the variables, as soon as we do this, the variables become inaccessible to any other class and can only be accessed using the methods of this class, let us see this through an example.

First let us see a code, without the 'private' keyword:

As you can see in the above code snippet, if you try to access the age and name variable of the Student class, you can access it using the object reference and there is no error.

Now, let us try the same after we add the 'private' keyword,

See, now when you try to access the age and name attributes it is giving you a compile error. Because now the age and String references are only accessible within the Student class.

So now the next question is, how do we set the values of these references if we can't access them?

One solution for that is since we can access these references inside the class, we can create a method, which takes two parameters as input and then assign those values to these references, let's see in it in the below code how to do that,

This is solving our issue of not being able to directly access the variables, there is no compile time and runtime error, and we are getting the desired result as well. However, this is not a standardized way.

The method name 'Values' is very vague and doesn't specify what actually it does, does it fetches a value for us? or is it setting a value for us? It's not clear by its name. Hence as a standard naming convention, we have two types of methods for getting and setting the values of a private variable, let's see what they are.

Setters and Getters.

  1. Setters:

    These are the methods that are used to set values for a variable.

    Their return type should be void, as these do not return any value.

    These should be public and the name should start with 'set' as per naming convention.

    Setters must accept an argument in order to set a value.

    public void setAge(int a) {
        age = a;
    }
  1. Getters:

    These are the methods that are used to get the values of a variable.

    Their return type cannot be void, as these need to return a value.

    These should be public and the name should start with 'get' as per naming convention.

    Getters do not accept any arguments.

    public int getAge() {
        return age;
    }

Let's see them in action in below code snippet,

class Student{
    private int age;
    private String name;

    public int getAge() {
        return age;
    }
    public void setAge(int a) {
        age = a;
    }
    public String getName() {
        return name;
    }
    public void setName(String n) {
        name = n;
    }

    void result(){
        System.out.println("Final Result is : Age is " + age + " and name is " + name);
    }
}

public class MyTest{
    public static void main(String []args){
        Student obj = new Student();
        obj.setAge(24);
        obj.setName("SHISHIR");
        System.out.println(obj.getAge());
        System.out.println(obj.getName());

        obj.result();
    }
}

Output:

[Running] cd "/config/workspace/" && javac MyTest.java && java MyTest

24
SHISHIR
Final Result is : Age is 24 and name is SHISHIR

[Done] exited with code=0 in 0.786 seconds

Note: To put some controls like string length or age can't be negative you can put a check before assigning the values to the variable. Only if the check passes do you assign the value, else display an error. That way you can put some controls over the value assignment.

Concluding all:

We use encapsulation to not expose the data to outside class, and to access it from outside class we use methods. As per conventions, we call these methods getters and setters.

There is another way of initializing the private variables, at the moment of object creation itself using the concept of 'Constructors'.

Constructors are the methods with have the same name as that of the class.

We have deliberately not touched this concept here, along with what is 'this' keyword, Shadowing problem. Will cover them in our next article. Till then have had fun reading it.



Thanks for coming this far in the article, I Hope I was able to explain the concept well enough. If in any case, you face any issues please feel free to reach out to me, I'd be happy to help.

You can always connect to me over LinkedIn to share feedback or queries by clicking here.