12.2 Encapsulation and Accessor Methods (getters and setters)
Encapsulation is one of the four fundamental pillars of object-oriented programming (OOP), alongside inheritance, polymorphism and abstraction. In Java, encapsulation is a technique that involves restricting direct access to an object's data and including specific methods within the class for manipulating that data. These methods are known as accessor methods, or more commonly, getters and setters.
Benefits of Encapsulation
Encapsulation offers a number of advantages for software development, which include:
Access Control
By encapsulating data, you can control who has access to it and under what conditions. This is done by defining access levels such as private
, protected
or public
. Attributes defined as private
can only be accessed by methods defined within the class itself, which protects the internal state of the object against unwanted access and modifications.
Flexibility and Maintenance
With encapsulation, the internal implementation of a class can be modified without affecting the classes that use it. This is because the implementation details are hidden behind the accessor methods. This way, you can change the internal code without worrying about the impact on other parts of the system that depend on this class, facilitating the maintenance and evolution of the software.
Modularity
Encapsulating the data of a class also helps to create clearer and more defined modules within the software. Each class becomes a "black box" that performs specific functions without revealing its internal mechanisms, which contributes to a more organized and understandable software architecture.
Protection against Misuse
Encapsulation protects the attributes of a class from misuse. For example, if an attribute must always be positive, you can guarantee this through a setter that rejects negative values. This prevents invalid states and potential bugs in the system.
Accessor Methods: Getters and Setters
Accessor methods are used to read (getters) and modify (setters) the values of attributes of a class. They are the public interface that the class offers to manipulate its internal data.
Getters
Getter methods are used to access the value of an attribute. They usually have the following form:
public Type getAttribute() {
return this.attribute;
}
This pattern allows other classes to read the attribute value without being able to modify it directly, preserving data integrity.
Setters
Setter methods are used to set or change the value of an attribute. They usually have the following form:
public void setAttribute(Type newValue) {
// Here you can include validations
if (newValue >= 0) {
this.attribute = newValue;
}
}
Setters allow you to validate data before modifying it, which helps maintain consistency and validity of the object's state.
Practical example
Consider a class ContaBancaria
that has a balance
attribute. Without encapsulation, any class could modify the balance directly, which could lead to inconsistent states, such as a negative balance. With encapsulation, the ContaBancaria
class might look like this:
public class ContaBancaria {
private double balance;
public double getBalance() {
return balance;
}
public void deposit(double value) {
if (value > 0) {
balance += value;
}
}
public void withdraw(double value) {
if (value > 0 && balance >= value) {
balance -= value;
}
}
}
In this example, the balance can only be modified through the deposit
and withdraw
methods, which include validations to ensure that the balance never becomes negative. The getSaldo
method allows reading the balance without the possibility of direct modification.
Conclusion
Encapsulation and the use of accessor methods are essential practices in object-oriented programming. They offer a way to protect and control access to an object's data, increasing the security, flexibility and modularity of the code. Furthermore, they facilitate software maintenance and evolution by allowing internal changes to be made without affecting other parts of the system. When designing your classes in Java, always considerencapsulation as a fundamental strategy for creating robust and reliable code.