BIG
DATA

JAVA

ENCAPSULATION IN OOP WITH EXAMPLES

Read more about »
  • Java 9 features
  • Read about Hadoop
  • Read about Storm
  • Read about Storm
 

Do you have your credit cards, money, and your driver's licenses in your wallet? Encapsulation is putting related things together to form a new object.

Definition

  • Encapsulation is the process of binding together the methods and data variables as a single entity. This keeps both the data and functionality code safe from the outside world. It hides the data within the class and makes it available only through the methods.
  • Encapsulation is a procedure of covering up of the data & functions into a single unit called as class
  • An encapsulated object is often called an abstract data type
  • Encapsulation is like enclosing in a capsule.
  • Encapsulation is the process of putting data and the operations (functions) that can be performed on that data into a single container called class. Now, any programmer can use this class without knowing how it is implemented. Due to encapsulation, data is insulated, thus not directly accessible from the outside world. This is known as Data Hiding.

Remember, Encapsulation is not data hiding, but, Encapsulation leads to data hiding.

Look at the example of a power steering mechanism of a car. Power steering of a car is a complex system, which internally have lots of components tightly coupled together, they work synchronously to turn the car in the desired direction. It even controls the power delivered by the engine to the steering wheel. But to the external world there is only one interface is available and rest of the complexity is hidden. Moreover, the steering unit in itself is complete and independent. It does not affect the functioning of any other mechanism.

Similarly, same concept of encapsulation can be applied to code. Encapsulated code should have following characteristics:

  • Everyone knows how to access it.
  • Can be easily used regardless of implementation details.
  • There shouldn't any side effects of the code, to the rest of the application.

The idea of encapsulation is to keep classes separated and prevent them from having tightly coupled with each other.



Example

A live example of encapsulation is the class of java.util.Hashtable. User only knows that he can store data in the form of key/value pair in a Hashtable and that he can retrieve that data in the various ways. But the actual implementation like, how and where this data is actually stored, is hidden from the user. User can simply use Hashtable wherever he wants to store Key/Value pairs without bothering about its implementation.

The whole idea behind encapsulation is to hide the implementation details from users. If a data member is private it means it can only be accessed within the same class. No outside class can access private data member (variable) of other class. However if we setup public getter and setter methods to update (for e.g.void setSSN(int ssn))and read (for e.g. int getSSN()) the private data fields then the outside class can access those private data fields via public methods. This way data can only be accessed by public methods thus making the private fields and their implementation hidden for outside classes. That's why encapsulation is known as data hiding. Lets see an example to understand this concept better.


public class EncapsulationDemo{
    private int ssn;    //private variables examples of encapsulation
    private String empName;
    private int empAge;

    //Getter and Setter methods
    public int getEmpSSN(){
        return ssn;
    }

    public String getEmpName(){
        return empName;
    }

    public int getEmpAge(){
        return empAge;
    }

    public void setEmpAge(int newValue){
        empAge = newValue;
    }

    public void setEmpName(String newValue){
        empName = newValue;
    }

    public void setEmpSSN(int newValue){
        ssn = newValue;
    }
}

public class EncapsTest{
    public static void main(String args[]){
         EncapsulationDemo obj = new EncapsulationDemo();
         obj.setEmpName("Mario");
         obj.setEmpAge(32);
         obj.setEmpSSN(112233);
         System.out.println("Employee Name: " + obj.getEmpName());
         System.out.println("Employee SSN: " + obj.getEmpSSN());
         System.out.println("Employee Age: " + obj.getEmpAge());
    } 
}

Output:


Employee Name: Mario
Employee SSN: 112233
Employee Age: 32

In above example all the three data members (or data fields) are private which cannot be accessed directly. These fields can be accessed via public methods only. Fields empName, ssn and empAge are made hidden data fields using encapsulation technique of OOPs.

Another Example of Encapsulation in Java

class Loan{
    private int duration;  //private variables examples of encapsulation
    private String loan;
    private String borrower;
    private String salary;
   
    //public constructor can break encapsulation instead use factory method
    private Loan(int duration, String loan, String borrower, String salary){
        this.duration = duration;
        this.loan = loan;
        this.borrower = borrower;
        this.salary = salary;
    }
   
    //no argument consustructor omitted here
    
   // create loan can encapsulate loan creation logic
    public Loan createLoan(String loanType){

     //processing based on loan type and than returning loan object
      return loan;
    } 
}

In this example of Encapsulation in Java you see all member variables are made private so they are well encapsulated you can only change or access this variable directly inside this class. if you want to allow outside world to access these variables is better creating a getter and setter e.g. getLoan() that allows you to do any kind of validation, security check before return loan so it gives you complete control of whatever you want to do and single channel of access for client which is controlled and managed.



Advantages of encapsulation

  • It improves maintainability and flexibility and re-usability: for e.g. In the above code the implementation code of void setEmpName(String name)and String getEmpName() can be changed at any point of time. Since the implementation is purely hidden for outside classes they would still be accessing the private field empName using the same methods (setEmpName(String name) and getEmpName()). Hence the code can be maintained at any point of time without breaking the classes that uses the code. This improves the re-usability of the underlying class.
  • The fields can be made read-only (If we don't define setter methods in the class) or write-only (If we don't define the getter methods in the class). For e.g. If we have a field(or variable) which doesn't need to change at any cost then we simply define the variable as private and instead of set and get both we just need to define the get method for that variable. Since the set method is not present there is no way an outside class can modify the value of that field.
  • User would not be knowing what is going on behind the scene. They would only be knowing that to update a field call set method and to read a field callget method but what these set and get methods are doing is purely hidden from them.


Encapsulation in java

When it comes to Encapsulation in java, we can simply define it saying:
Encapsulation is a practice to bind related functionality (Methods) & Data (Variables) in a protective wrapper (Class) with required access modifiers (public, private, default & protected) so that the code can be saved from unauthorized access by outer world and can be made easy to maintain.

We can achieve complete encapsulation in java by making members of a class private and access them outside the class only through getters and setters. Although a lesser degree of encapsulation can be achieved by making the members public or protected. Encapsulation makes it possible to maintain code that is frequently changeable by took that in one place and not scatter everywhere.

So, we can conclude our discussion saying that, Encapsulation is reflected with a well defined class having all related data and behavior in a single place and than access/restrict it using appropriate access modifiers



Why Use Encapsulation?

The purpose of Encapsulation is to achieve potential for change: the internal mechanisms of the component can be improved without impact on other components, or the component can be replaced with a different one that supports the same public interface. Encapsulation also protects the integrity of the component, by preventing users from setting the internal data of the component into an invalid or inconsistent state. Another benefit of encapsulation is that it reduces system complexity and thus increases robustness, by limiting the interdependencies between software components.

In this sense, the idea of encapsulation is more general than how it is applied in OOP: for example, a relational database is encapsulated in the sense that its only public interface is a Query language (SQL for example), which hides all the internal machinery and data structures of the database management system. As such, encapsulation is a core principle of good software architecture, at every level of granularity.

Some programmers may think encapsulation is simply a clever way to make your program orderly by putting related attributes and procedures under one roof. Although this is true, protection is the reason for encapsulation.
In my experience, encapsulation makes doing the "wrong" thing much more difficult. It can also help hide the details from the end user which may help increase safety and reliability.

Consider that you have a fruit object. One natural thing is to cut this fruit. So you write a cut() function, so you can do

cut(fruit) 
with a new fruit object you've created. This makes sense. But if you're not careful, you might accidentally call
cut(finger) 
with a finger object somewhere in your project. This could lead to very bad things. Instead, encapsulate this function/method into a Fruit class so you can do this
fruit.cut() 

This definitely helps to avoid calling finger.cut() accidentally, since finger probably doesn't have a cut() method associated with it. This is a bit of artificial and unrealistic example but I've found it helpful. Encapsulation can sometimes be an underrated aspect of OOP, but it's a good one.

The real use of encapsulation is also the fact that you can do additional checks/processing on the fly the values are set.

Assume you have an age property.
The user can enter a value of -10, which although is a valid number, is an invalid age. A setter method could have logic which would allow you to catch such things.
Another scenario, would be to have the age field, but hidden. You could also have a Date of Birth field, and in it's setter you would have something like so:

...
private int age
private Date dob

...
public void setDateOfBirth(Date dob)
{
    this.dob = dob;
    age = ... //some logic to calculate the age from the Date of Birth.
}


Real Life Examples

[1] TV operation
It is encapsulated with cover/box and we can operate with remote and no need to open TV and change the channel. Here everything is in private except remote so that anyone cannot access/operate and change the things in TV.

[2] Bag
Encapsulation is like your bag in which you can keep your pen, book etc. It means this is the property of encapsulating members and functions.

[3] Cars and owners
ax All the functions of cars are encapsulated with the owners.. No one else can access it...

[4] Capsule that the doctor gives
Just think of a capsule that the doctor gives us. We just have to take the capsule to get better. We don't have to worry about what medicine is inside the capsule or how it will work on our body.
What it means that we give access to our class via proper methods and properties. The user does not have to worry how this methods and properties work.

[5] School bag
Think of your school Bag in which you keep all your stuff like books and pens and document etc. to keep it safe from the outside world. Here you are hiding your books and pen by putting them inside the Bag similarly in OOP we encapsulate the data and methods inside the class to keep it safe and accessible only to authorized member.



Benefits of Encapsulation
  • Encapsulation brings Simplicity and clarity and hence better understanding.
  • A class can have total control over what is stored in its fields. Suppose you want to set the value of marks field i.e. marks should be positive value, than you can write the logic of positive value in setter method.
  • By providing only getter and setter method access, you can make the class read only.
  • Encapsulated Code is more flexible and easy to change with new requirements.
  • Encapsulation in Java makes unit testing easy.
  • Encapsulation also helps to write immutable class in Java which are a good choice in multi-threading environments.
  • Encapsulation allows you to change one part of code without affecting other part of code.
What should you encapsulate in code
There is a famous design principle, which says: "Whatever changes encapsulate it". So anything which can be changed or more likely to change in near future is candidate of Encapsulation. This also helps to write more specific and cohesive code.

Difference between Encapsulation and Abstraction
This is one of the most frequently asked and discussed question in OOP. Encapsulation and Abstraction are purely different scenarios.
  • Abstraction lets you focus on what the object does instead of how it does. Encapsulation means hiding the internal details or mechanics of how an object does something. Like when you drive a car, you know what the gas pedal does but you may not know the process behind it because it is encapsulated.
  • Encapsulation means-hiding data like using getter and setter etc. Abstraction means- hiding implementation using abstract class and interfaces etc.
  • Encapsulation helps in adhering to Single Responsibilty principle and Abstraction helps in adhering to Code to Interface and not to implement.
    Say I have a class for Car.
    For Abstraction : we define abstract Class for CAR and define all the abtract methods in it , which are function available in the car like : changeGear(), applyBrake().
    Now the actual Car (Concrete Class i.e. like Mercedes , BMW will implement these methods in their own way and abstract the execution and end user will still apply break and change gear for particular concrete car instance and polymorphically the execution will happen as defined in concrete class.
    For Encapsulation : Now say Mercedes come up with new feature/technology: Anti Skid Braking, while implemeting the applyBrake(), it will encapsulate this feature in applyBrake() method and thus providing cohesion, and service consumer will still access by same method applyBrake() of the car object. Thus Encapsulationin lets further enhacment in same concrete class implementation.
  • In TV, TV connections, wiring and display panel is hidden inside the TV case which is not been exposed for viewers like us and exposed only neccessary things of a TV like TV Channel keys, TV volume keys, ON/OFF switch, Cable Switch and TV remote control for viewers to use it.
    This means TV connections and display panel and wiring is an unwanted data and not needed for viewers to see is being hidden from outside the world.
    So encapsulation means hiding the important features of a class which is not been needed to be exposed outside of a class and exposing only necessary things of a class. Here hidden part of a class acts like Encapsulation and exposed part of a class acts like Abstraction.


Points of Interests
  • If someone asks, what is the differce between encapsulation and information hiding, It sees both are the same from your explanation.
    Then you say:Encapsulation and information hiding are much related concepts, information hiding is achieved using Encapsulation.