Encapsulation
What is encapsulation? Explain with a code. Why it is important or needed and how?
Encapsulation means binding our data with methods in a single unit /class only ways to access to those data is methods and nobody can outside directly access this variable
Benefits:
Setter methods can include validation logic to ensure that any data being set meets certain criteria
Example: check the amount > 500 in Bank Class deposit()
Hides the implementation logics of validation
Can set read-only or write-only access only to that variable
Example: read-only access to accounNumber in Bank Class
Hides implementation logics and rest of the code depends on the method only. you can change implementation logics any time any outside can't don't know about it.
Example : withdraw() and deposit() function in Bank Classs
Encapsulation in Java
Encapsulation is one of the fundamental principles of Object-Oriented Programming (OOP) that refers to the bundling of data (variables) and methods (functions) into a single unit, typically a class and it restricts direct access to some of the object's components.
Why Encapsulation?
Access modifiers are mainly used for encapsulation. It can help us to control what part of a program can access the members of a class
It prevents outer classes from accessing and changing fields and methods of a class. This also helps to achieve data hiding.
Encapsulation refers to the bundling of related fields and methods together. This can be used to achieve data hiding. Encapsulation in itself is not data hiding.
Suppose age is private of Person class that means why cannot directly access it like p1.age = 24; for access it we need to the getter and setter method which only known by the developer it written the code and even we cannot know whether it is read-only or write-only or both: This called Data Hiding
The getter and setter methods provide read-only or write-only access to our class fields.
It helps to control the values of our data fields
Example Code:
public class EncapsulatedEmployee {
// Private variables to restrict direct access
private String name;
private int age;
private double salary;
// Constructor
public EncapsulatedEmployee(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
// Public getter and setter methods to provide controlled access
public String getName() {
return name;
}
public void setName(String name) {
// Additional logic or validation can be added here
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age > 0) { // Validation example
this.age = age;
} else {
System.out.println("Please enter a valid age.");
}
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
if(salary > 0) { // Validation example
this.salary = salary;
} else {
System.out.println("Please enter a valid salary.");
}
}
public void displayInfo() {
System.out.println("Employee Name: " + name);
System.out.println("Employee Age: " + age);
System.out.println("Employee Salary: $" + salary);
}
}
public class Main {
public static void main(String[] args) {
// Creating an object of EncapsulatedEmployee
EncapsulatedEmployee emp = new EncapsulatedEmployee("John Doe", 30, 50000.0);
// Accessing the employee information using public methods
emp.displayInfo();
// Modifying the employee information using setter methods
emp.setName("Jane Doe");
emp.setAge(28);
emp.setSalary(60000.0);
// Displaying the updated employee information
emp.displayInfo();
}
}
Explanation:
Private Variables: The variables
name
,age
, andsalary
are declared as private, so they cannot be accessed directly from outside the class.Public Methods: Public getter and setter methods are provided to access and update the private variables. This allows for controlled access.
Validation: Setter methods include validation logic to ensure the data remains consistent and valid.
Main Class: In the
Main
class, we create an instance ofEncapsulatedEmployee
and access its properties using the public methods.
By using encapsulation, we ensure that the internal state of the EncapsulatedEmployee
object is protected from unintended or harmful changes from outside the class, while still providing a way to access and modify it in a controlled manner.
If there is public get and set method, how it restricts access...? What the use case?
Understanding Encapsulation with Getters and Setters
The concept of encapsulation can be confusing when considering the use of public getters and setters. While getters and setters do provide access to private fields, they still play a crucial role in encapsulation. Here’s why and how they are useful:
Controlled Access
Validation: Setters can include validation logic to ensure that only valid data is set. This prevents the internal state from being corrupted by invalid values.
public void setSalary(double salary) { if (salary >= 0) { this.salary = salary; } else { System.out.println("Invalid salary. Must be non-negative."); } }
public void setAge(int age) { if (age > 0) { this.age = age; } else { System.out.println("Please enter a valid age."); } }
Read-Only or Write-Only Properties: By providing only a getter or a setter, you can make a field read-only or write-only.
// Read-only property public int getAge() { return age; } // Write-only property public void setPassword(String password) { // logic to set password }
Encapsulation of Behavior: Getters and setters allow you to change the internal implementation without affecting external code. For example, you could change how a property is calculated internally without changing how it’s accessed.
public double getSalary() { return salary * 1.10; // Adding a 10% bonus, for example }
Example Code with Controlled Access
Here's a more detailed example that showcases controlled access and validation:
public class BankAccount {
private String accountNumber;
private double balance;
public BankAccount(String accountNumber, double initialBalance) {
this.accountNumber = accountNumber;
if (initialBalance >= 0) {
this.balance = initialBalance;
} else {
this.balance = 0;
}
}
// Getter for accountNumber (read-only)
public String getAccountNumber() {
return accountNumber;
}
// Getter for balance
public double getBalance() {
return balance;
}
// Setter for balance with validation
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
} else {
System.out.println("Deposit amount must be positive.");
}
}
// Method to withdraw money with validation
public void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
} else {
System.out.println("Invalid withdraw amount.");
}
}
public static void main(String[] args) {
BankAccount account = new BankAccount("123456789", 1000.0);
// Display initial balance
System.out.println("Account Number: " + account.getAccountNumber());
System.out.println("Initial Balance: " + account.getBalance());
// Deposit money
account.deposit(500.0);
System.out.println("Balance after deposit: " + account.getBalance());
// Withdraw money
account.withdraw(300.0);
System.out.println("Balance after withdrawal: " + account.getBalance());
// Try to withdraw an invalid amount
account.withdraw(1500.0);
System.out.println("Balance after invalid withdrawal attempt: " + account.getBalance());
}
}
Explanation
Validation: The
deposit
andwithdraw
methods include validation to ensure that the operations are only performed with valid amounts.Read-Only Property: The account number is read-only; there is no setter for it.
Controlled Access: The balance can only be modified through the
deposit
andwithdraw
methods, which ensures that the balance can never be set to an invalid state.
By using getters and setters, we can encapsulate the internal state and ensure that only valid operations are performed, thus maintaining the integrity of the object.
Last updated