Object Oriented Programming || Encapsulation
Tags: oops, java
Published: 2024-07-03 10:42:42

As we all know that encapsulation is one of the 4 pillars of OOPS and we can use this to hide the data and add some restrictions to perform the operation on the instance varaible of the classs for which we want to make sure that encapsulation has been done perfectly.
Genrally We have been told that we have to hide the variable to make so that nobody can change it except the class it self in which this variable has been defined. So to access this varaible outside the class (if needed) we define the getter and setter method so that we can perfom the necessary operations related to that instance vairbale.
_Refer to the Java Example Code below::_
```
// Class for a bank account Holder
public class BankAccountHolder {

    // Private fields to store account information
    private String accountNumber;
    private String accountHolderName;
    private double balance;

    // Public constructor to initialize a new BankAccount
    public BankAccount(String accountNumber, String accountHolderName, double initialBalance) throws Exception {
        setAccountNumber(accountNumber);
        setAccountHolderName(accountHolderName);
        setBalance(initialBalance);
    }

    // Public getter for accountNumber
    public String getAccountNumber() {
        return accountNumber;
    }

    // Private setter for accountNumber
    private void setAccountNumber(String accountNumber) throws Exception {
        if (accountNumber != null && !accountNumber.isEmpty()) {
            this.accountNumber = accountNumber;
        } else {
            throw new Exception("Invalid account number.");
        }
    }

    // Public getter for accountHolderName
    public String getAccountHolderName() {
        return accountHolderName;
    }

    // Public setter for accountHolderName
    public void setAccountHolderName(String accountHolderName) throws Exception {
        if (accountHolderName != null && !accountHolderName.isEmpty()) {
            this.accountHolderName = accountHolderName;
        } else {
            throw new Exception("Invalid account holder name.");
        }
    }

    // Public getter for balance
    public double getBalance() {
        return balance;
    }

    // Private setter for balance
    private void setBalance(double balance) throws Exception {
        if (balance >= 0) {
            this.balance = balance;
        } else {
            throw new Exception("Invalid initial balance.");
        }
    }
}
```
In the example above, we have 3 variables as _accountNumber, accountHolderName, balance_ as private method and we have defined the getters and setters for each of these 3 so that If used other class wants to use the instance variables, they can easily use.
But that’s not all suppose we want 2 more methods here as well so that we can deposit and withdraw from this account.
Please note that here we are not discussing the application level security and we are assuming that our team has done the perfect job to authorize the user.
So with the new two methods while performing the job of withdraw and deposit the amount we will try to avoid the direct call to instance variable “balance”. Insted of this we update this with the setter method as the setter method is making sure that if any of the rule is breaking for the instance variable, it will thorw the exception.
Below are deposit and withdraw methods code which we will add in the BankAccountHolder class.

```
 public void deposit(double amount) throws Exception {
        if (amount > 0) 
            int finalBalance = this.getBalance() + amount;
            setBalance(finalBalance);
        } else {
            throw new Exception("Deposit amount must be positive.");
        }
    }

    // Public method to withdraw an amount from the account
    public void withdraw(double amount) throws Exception {
        if (amount > 0 && amount <= this.getBalance()) {
            int finalBalance = this.getBalance() - amount;
            setBalance(finalBalance);
        } else {
            throw new Exception("Invalid withdrawal amount.");
        }
    } 
```

**Summary: We will try avoid to call the instance variable directly in the class as well to meet the standards of the security inside our code.**