Java > Object-Oriented Programming (OOP) > Encapsulation > Encapsulation in Practice
Encapsulation Example: Bank Account
This example demonstrates encapsulation using a BankAccount
class. It hides the internal state (balance) and exposes controlled access through methods.
BankAccount Class Definition
The BankAccount
class encapsulates the balance
and accountNumber
attributes. These are declared as private
, meaning they can only be accessed directly from within the BankAccount
class. Access to these attributes is controlled through public methods: getBalance()
, getAccountNumber()
, deposit()
, and withdraw()
. The deposit
and withdraw
methods include validation to ensure data integrity (e.g., preventing negative deposits or withdrawals exceeding the balance). The Main
class demonstrates how to create and interact with a BankAccount
object.
public class BankAccount {
private double balance;
private String accountNumber;
public BankAccount(String accountNumber, double initialBalance) {
this.accountNumber = accountNumber;
this.balance = initialBalance;
}
public double getBalance() {
return balance;
}
public String getAccountNumber() {
return accountNumber;
}
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
System.out.println("Deposited: " + amount + ", New balance: " + balance);
} else {
System.out.println("Invalid deposit amount.");
}
}
public void withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
System.out.println("Withdrawn: " + amount + ", New balance: " + balance);
} else {
System.out.println("Insufficient funds or invalid withdrawal amount.");
}
}
}
public class Main {
public static void main(String[] args) {
BankAccount account = new BankAccount("12345", 1000.0);
System.out.println("Account Number: " + account.getAccountNumber());
System.out.println("Initial Balance: " + account.getBalance());
account.deposit(500.0);
account.withdraw(200.0);
account.withdraw(1500.0);
}
}
Concepts Behind the Snippet
Encapsulation is a fundamental OOP principle that involves bundling data (attributes) and methods that operate on that data into a single unit (a class), and hiding the internal state of the object from the outside world. This promotes data integrity and reduces complexity. Private attributes and public getter/setter methods are key elements.
Real-Life Use Case
Consider a software system for managing employee records. Employee salary information should be encapsulated within the Employee
class and only accessible through methods like getSalary()
and updateSalary()
, potentially with appropriate authorization checks. This prevents unauthorized access and modification of sensitive data.
Best Practices
Always use private
access modifiers for instance variables unless there's a specific reason to expose them directly. Provide getter and setter methods (accessors and mutators) to control how the data is accessed and modified. Include validation logic in setter methods to ensure data integrity.
Interview Tip
Be prepared to explain the benefits of encapsulation, such as data hiding, improved code maintainability, and reduced coupling. Also, be ready to discuss scenarios where encapsulation might not be strictly necessary (e.g., in very simple classes with limited functionality).
When to Use Them
Use encapsulation whenever you want to protect the internal state of an object and control how it's accessed and modified. It's particularly important when dealing with sensitive data or when you want to enforce specific business rules.
Memory Footprint
Encapsulation itself doesn't directly affect memory footprint. The memory footprint is determined by the data types of the instance variables. However, the methods defined to access and manipulate the encapsulated data will contribute to the overall size of the class in memory, although this contribution is generally small.
Alternatives
While encapsulation is a core OOP principle, alternatives might include using data structures with limited access control (e.g., immutable objects) or using functional programming paradigms where data transformation is emphasized over mutable state.
Pros
Cons
FAQ
-
What is the difference between public, private, and protected access modifiers?
- Public: Accessible from anywhere.
- Private: Accessible only from within the same class.
- Protected: Accessible from within the same class, subclasses, and other classes in the same package.
-
Why should I use getters and setters instead of directly accessing instance variables?
Getters and setters allow you to control how the data is accessed and modified. You can add validation logic, implement lazy loading, or perform other actions when the data is accessed or modified. This provides greater flexibility and control over the object's state.