OOP(s): The Encapsulation

OOP(s): The Encapsulation

Quote

Once an object escapes, you have to assume that another class or thread may, maliciously or carelessly, misuse it. This is a compelling reason to use encapsulation; it makes it practical to analyze programs for correctness and harder to violate design constraints accidentally.

encapsulate_1.png

Let us assume an example, a person "A" has a bank account in Bank of Mars, if his details are accessed by others within the bank then an alien could set his account balance to 0, less than that, or that alien could make him the richest on mars, or alter his personal details, or something else, who knows.

The reason why alien has access to A's details is that those aren't hidden. That is exactly what encapsulation provides in Object Oriented Programming Paradigm.

Encapsulation: The Definition

Encapsulation refers to the bundling of fields and methods inside a single class. It prevents outer classes from accessing and changing the fields and methods of a class. This also helps to achieve data hiding.

Encapsulation_1.gif

Encapsulation: The Example

Consider the following class Area, which takes length, and breadth from the user and calculates the area by calling the getArea() method.

Example:

class Area {

  int length;
  int breadth;

  Area(int length, int breadth) {
    this.length = length;
    this.breadth = breadth;
  }

  public void getArea() {
    int area = length * breadth;
    System.out.println("Area: " + area);
  }
}

class Main {
  public static void main(String[] args) {
    Area rectangle = new Area(5, 6);
    rectangle.getArea();
  }
}

This is only encapsulation. We are just keeping similar codes together. Here, the fields and methods can be accessed from other classes as well. Hence, this is not data hiding.

  • The bundling of related data and procedures is referred to as encapsulation. This can be used to conceal data. Encapsulation in itself is not data hiding.

Encapsulation: The Example - II

Data Hiding

Data hiding is a way of restricting the access of our data members by hiding the implementation details. Encapsulation also provides a way for data hiding.

Example:

Consider the following class without encapsulation,

class accountHolder{
    public int accountNumber;
    public String accountHolderName;
    public String accountHolderAddress;
    public String accountHolderPhonenumber;
    public Float accoutBalance;
}

From the above class, we can modify all fields from another class,

class accountDetailsModifier{
     public void modify(accountHolder accountholder){
          //Passing the accountHolder object in here.
          accountholder.accountNumber = //Set new Account Number;
          accountholder.accountHolderName = // Set new Account Holder Name
          accountholder.accountBalance = // Set new balance to account
     }
}

As we can see that any outer class can modify the fields of accountHolder class, now try to encapsulate things in class.

public class accountHolder {
    private int accountNumber;
    private String accountHolderName;
    private String accountHolderAddress;
    private String accountHolderPhonenumber;
    private Float accountBalance;

    public int getAccountNumber() {
        return accountNumber;
    }

    /**
     * Once an accountNumber has been issued, we can't set it again.
     */
    // public void setAccountNumber(int accountNumber) {
    //     this.accountNumber = accountNumber;
    // }

    public String getAccountHolderName() {
        return accountHolderName;
    }
    public void setAccountHolderName(String accountHolderName) {
        this.accountHolderName = accountHolderName;
    }

    public String getAccountHolderAddress() {
        return accountHolderAddress;
    }

    public void setAccountHolderAddress(String accountHolderAddress) {
        this.accountHolderAddress = accountHolderAddress;
    }
    public String getAccountHolderPhonenumber() {
        return accountHolderPhonenumber;
    }

    public void setAccountHolderPhonenumber(String accountHolderPhonenumber) {
        this.accountHolderPhonenumber = accountHolderPhonenumber;
    }

    public Float getAccoutBalance() {
        return accountBalance;
    }

    public void setAccoutBalance(Float accountBalance) {
        if(accountBalance < 0){
            throw new Exception("Error : Can't set accout balance to negative.");
        }

        this.accountBalance = accountBalance;
    }

}

As we can see in the above code whenever someone tries to access our private fields, they could only achieve it through setters() and getters(), where setters are used to set values to fields, and getters are used to get the class fields.

Making accountBalance private allowed us to restrict unauthorized access from outside the class. This is data hiding.

new accountHolder().accountBalance = -10**9 
//Throws error:  accountBalance has private access in accountHolder.

Finally

Encapsulation : The Advantages

  • Encapsulation in Java allows us to keep similar fields and methods together, making our code simpler and easier to read.
  • It helps to control the values of our data fields.
  • It helps to decouple components of a system. For example, we can encapsulate code into multiple bundles.

    These decoupled components (bundle) can be developed, tested, and debugged independently and concurrently. And, any changes in a particular component do not have any effect on other components.

  • We can also achieve data hiding using encapsulation.