Java > Object-Oriented Programming (OOP) > Encapsulation > Private Fields and Public Methods
Encapsulation with Private Fields and Public Getters/Setters in Java
This snippet demonstrates encapsulation, a core OOP principle, by using private fields to protect data and public methods (getters and setters) to control access to that data. This approach promotes data integrity and allows for controlled modification.
Code Example: `BankAccount` Class
The `BankAccount` class has `accountNumber` and `balance` as private fields. This means they can only be accessed directly from within the `BankAccount` class itself. Public methods like `getAccountNumber()`, `getBalance()`, `deposit()`, and `withdraw()` provide controlled access. The deposit and withdraw methods include logic to prevent invalid operations (e.g., depositing negative amounts or withdrawing more than the balance). The `setAccountNumber` method allow modification of the account number, we can put validation to keep the data integrity.
public class BankAccount {
private String accountNumber;
private double balance;
public BankAccount(String accountNumber, double initialBalance) {
this.accountNumber = accountNumber;
this.balance = initialBalance;
}
public String getAccountNumber() {
return accountNumber;
}
public double getBalance() {
return balance;
}
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
public void withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
}
}
public void setAccountNumber(String accountNumber) {
// Can add validation here to prevent setting an invalid account number
this.accountNumber = accountNumber;
}
public static void main(String[] args) {
BankAccount account = new BankAccount("1234567890", 1000.0);
System.out.println("Account Number: " + account.getAccountNumber());
System.out.println("Balance: " + account.getBalance());
account.deposit(500.0);
System.out.println("Balance after deposit: " + account.getBalance());
account.withdraw(200.0);
System.out.println("Balance after withdrawal: " + account.getBalance());
account.setAccountNumber("0987654321");
System.out.println("New Account Number: " + account.getAccountNumber());
}
}
Concepts Behind the Snippet
Encapsulation: Bundling data (fields) and methods that operate on that data within a single unit (class). This helps in hiding the internal state of an object and prevents direct access from outside the class.
Data Hiding: Making fields private ensures that the internal representation of an object is hidden from the outside world. External code can only interact with the object through its public methods.
Getters and Setters: Getter methods (like `getAccountNumber()`) provide read-only access to the private fields. Setter methods (like `setAccountNumber()`) allow modifying the private fields, often with validation logic to ensure data integrity.
Real-Life Use Case
Consider a system managing employee information. An `Employee` class might have private fields like `salary`, `socialSecurityNumber`, and `performanceRating`. Public getter methods can provide access to `salary` and `performanceRating` for reporting purposes. The `socialSecurityNumber` might not have a getter at all, or it might be restricted to only certain authorized personnel via specific access control mechanisms within the getter method. Setter methods might be used to update `performanceRating`, but changes to `socialSecurityNumber` could be highly restricted and require audit logging.
Best Practices
Interview Tip
When discussing encapsulation in an interview, emphasize its role in data hiding, data integrity, and code maintainability. Be prepared to explain how private fields and public methods contribute to these benefits. Also, be ready to discuss scenarios where using encapsulation might be overkill (e.g., very simple data transfer objects).
When to Use Them
Use private fields and public methods (getters and setters) whenever you want to control how data is accessed and modified within a class. This is particularly important when:
Avoid using them when you are working on simple data transfer objects where you only need to store and retrieve data, and there's no need for validation or protection.
Memory Footprint
Using private fields and public methods (getters and setters) does not significantly impact memory footprint. The memory occupied by the fields remains the same regardless of whether they are private or public. The getter and setter methods add a small overhead to the code size, but this is generally negligible.
Alternatives
Pros
Cons
FAQ
-
Why use private fields instead of public fields?
Private fields provide data hiding and allow you to control how data is accessed and modified, ensuring data integrity and preventing unintended side effects. -
When should I use a setter method?
Use a setter method when you need to allow modification of a field, but you also want to enforce validation rules or perform other actions when the field is changed. -
Is it always necessary to have both a getter and a setter for a private field?
No. You only need to provide a getter if you need to allow external code to read the field's value, and you only need to provide a setter if you need to allow external code to modify the field's value. If a field should be read-only, provide only a getter. If a field should be write-only (rare), provide only a setter.