Encapsulation in Java
Encapsulation is one of the fundamental principles of Object-Oriented Programming (OOP). It is the mechanism of restricting direct access to some of an object's components and providing controlled access through public methods. This helps protect the internal state of an object from unintended modifications.
What is Encapsulation?
Encapsulation refers to the concept of wrapping data (variables) and code (methods) together as a single unit. It allows data hiding by making the variables private and providing public getter and setter methods to access and update the values of the variables.
Benefits of Encapsulation
- Data Hiding: By restricting direct access to fields, encapsulation ensures that the internal state of an object cannot be changed directly, leading to a more controlled and predictable behavior.
- Code Maintainability: Encapsulation allows changes to be made in the class without affecting other classes that use it. This makes the code more flexible and easier to maintain.
- Security: Encapsulation helps protect data by preventing unauthorized access and modification.
1. Example of Encapsulation
Let's create a class Person that demonstrates encapsulation by having private variables and public getter and setter methods to access and update the values.
Step-by-Step Example:
class Person {
// Private variables
private String name;
private int age;
// Getter method for name
public String getName() {
return name;
}
// Setter method for name
public void setName(String name) {
this.name = name;
}
// Getter method for age
public int getAge() {
return age;
}
// Setter method for age
public void setAge(int age) {
if (age > 0) { // Validating that age is positive
this.age = age;
} else {
System.out.println("Invalid age.");
}
}
}
public class Main {
public static void main(String[] args) {
// Creating an object of the Person class
Person person = new Person();
// Using setter methods to set values
person.setName("John");
person.setAge(30);
// Using getter methods to access values
System.out.println("Name: " + person.getName());
System.out.println("Age: " + person.getAge());
}
}
Output:
Name: John
Age: 30
Explanation:
- The variables
nameandageare declared as private to hide them from direct access outside thePersonclass. - The getter methods (
getName()andgetAge()) allow access to the private variables. - The setter methods (
setName()andsetAge()) allow modification of the private variables, with validation in thesetAge()method to ensure the age is positive. - The
thiskeyword refers to the current instance of the class, distinguishing between the parameter and the instance variable.
2. Encapsulation with Validation
In the previous example, we included validation in the setter method for age to ensure that only valid values are set. This is one of the key advantages of encapsulation — it allows validation of input and ensures that the object’s state remains valid.
Example with Validation:
class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
if (name != null && !name.isEmpty()) {
this.name = name;
} else {
System.out.println("Invalid name.");
}
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 0) {
this.age = age;
} else {
System.out.println("Invalid age.");
}
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person();
// Setting valid values
person.setName("Alice");
person.setAge(25);
System.out.println("Name: " + person.getName());
System.out.println("Age: " + person.getAge());
// Setting invalid values
person.setName(""); // Invalid name
person.setAge(-5); // Invalid age
}
}
Output:
Name: Alice
Age: 25
Invalid name.
Invalid age.
Explanation:
- In this example, we added validation for the
namein the setter methodsetName(), ensuring that an empty string ornullis not accepted. - If the validation fails, an error message is printed instead of updating the object's state, ensuring that the object remains in a valid state.
3. Access Control in Encapsulation
Encapsulation also provides access control by restricting access to the object's data. By making fields private and using public methods to access them, we can control how the data is accessed and modified. This is an example of information hiding.
Example with Different Access Modifiers:
class Person {
private String name; // Private field
protected int age; // Protected field
public String address; // Public field
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 0) {
this.age = age;
} else {
System.out.println("Invalid age.");
}
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person();
// Using getter and setter methods for private field
person.setName("John");
// Accessing protected field directly (possible within the same package)
person.age = 30;
// Accessing public field directly
person.address = "123 Main St";
System.out.println("Name: " + person.getName());
System.out.println("Age: " + person.age);
System.out.println("Address: " + person.address);
}
}
Output:
Name: John
Age: 30
Address: 123 Main St
Explanation:
- The
namefield is private and can only be accessed or modified through the getter and setter methods. - The
agefield is protected, meaning it can be accessed by subclasses or classes within the same package. - The
addressfield is public and can be accessed directly from anywhere in the program.
4. Conclusion
Encapsulation is an important concept in Java that helps protect the internal state of an object from external interference and misuse. By making fields private and providing public getter and setter methods, encapsulation allows controlled access to an object's data. It also allows for validation, improving data integrity and security in your program.