In this chapter, we will talk about the concept of encapsulation and information hiding, critical fundamentals in object-oriented programming, as they promote a safer and more maintainable software design.
On one hand, encapsulating, grouping data and behavior in the same place, and on the other, hiding, not making internal details visible and also controlling access.
We will see how these concepts help protect data and structure code in a more logical and robust way.
# What is Encapsulation?
Encapsulation is one of the four fundamental principles of object-oriented programming.
It refers to the practice of grouping data (attributes) and methods that operate on those data in a single entity, or class, and restricting access to certain components of that class.
This not only protects data from improper access but also makes the code easier to maintain and understand.
# Information Hiding
Information hiding is strongly linked to encapsulation. It is about hiding internal details of a class's operation and exposing only what is necessary for the rest of the program.
This means that users of a class do not need to understand its internal complexity to be able to use it.
# Access Modifiers
In most languages, including Java, access modifiers exist to set the level of access to classes, constructors, methods, and variables. The most common are:
-
private: The member is only accessible within the same class.
-
public: The member is accessible from any class.
-
protected: The member is accessible within its own class, in classes of the same package, and in subclasses.
-
No modifier (default): The member is accessible only within its own package.
# Getters and Setters
Getters and setters are methods that allow reading and modifying, respectively, the value of a class's private attributes.
These are a classic example of encapsulation and information hiding:
-
Getters: Methods that return an attribute's value.
-
Setters: Methods that set or update an attribute's value.
# Example
Refactor a class to apply encapsulation principles.
We have the "BankAccount" class that does not use encapsulation:
public class BankAccount {
public String owner;
public double balance;
public void deposit(double amount) {
balance += amount;
}
public void withdraw(double amount) {
balance -= amount;
}
}
From anywhere, you can directly access the owner or balance attributes.
BankAccount myAccount = new BankAccount();
myAccount.owner = "John Doe";
We refactor this class to apply encapsulation:
public class BankAccount {
// Private attributes
private String owner;
private double balance;
// Constructor
public BankAccount(String owner, double initialBalance) {
this.owner = owner;
this.balance = initialBalance;
}
// Getters and Setters
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public double getBalance() {
return balance;
}
// Methods to deposit and withdraw
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
public void withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
}
}
}
In this version, the owner and balance attributes are private, which means they cannot be modified directly from outside the class. Instead, getters and setters methods are used to access and modify these values, allowing for validation and control over how and when data is accessed.
BankAccount myAccount = new BankAccount();
myAccount.setOwner("John Doe");
# Conclusions
Encapsulation and information hiding are key concepts in object-oriented programming; they help protect data and make code safer, more organized, and maintainable.
By using access modifiers, getters, and setters, you can control how an object's internal state is accessed and modified, which leads to more robust and reliable applications.
As you continue your journey in programming, you will realize that encapsulation is not just a technique, but a philosophy that guides solid and effective software design.