Encapsulation in Java
Learn more about encapsulation in Java.
Join the DZone community and get the full member experience.
Join For FreeIn this blog, I will try to explain the encapsulation principle in Java as simply as possible.
If you do a little research, you will discover that encapsulation is one of the three main principles of OOP. To achieve encapsulation in Java, you need to:
1. Declare variables of a class as private
2. Provide public setter and getter methods to read and write the values of variables
This is further demonstrated in the following example:
public class Coat {
private double price;
private String customer;
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getCustomer() {
return customer;
}
public void setCustomer(String customer) {
this.customer = customer;
}
}
Now, let's talk more about the benefits of encapsulation:
- Other classes will not be able to access data directly because variables are private.
- You can make the class read-only (by creating only getter methods) or write-only (by creating only setter methods).
- You can control your data. In setter and getter methods, you can write the logic for special conditions.
- It improves flexibility and reusability.
After learning the benefits of encapsulation, you might ask: How did you achieve these benefits by only declaring variables as private and setting setter and getter methods for them? Which problems can occur if we don’t follow encapsulation principle?
Most beginners will ask these questions at first. But the answers to these questions are not very difficult to comprehend. We just need to make our example more complex. This is because if the example is too simple, we cannot show you how to prevent problems that might occur in future uses of a class. Let’s make some adjustments to our code and explain the benefits one by one:
Assume that the price of a coat changes due to the customer. If a customer is a student, he or she gets a 20 percent discount. Therefore, getPrice()
and setPrice()
methods should look like this:
public double getPrice() {
return price;
}
public void setPrice(double price) {
if(customer.equals("student")){
this.price = price * 0.8;
}else{
this.price = price;
}
}
Now, if there is no encapsulation, the Coat
class is:
public class Coat {
//instance variables are public
public double price;
public String customer;
public double getPrice() {
return price;
}
public void setPrice(double price) {
if(customer.equals("student")){
this.price = price * 0.8;
}else{
this.price = price;
}
}
public String getCustomer() {
return customer;
}
public void setCustomer(String customer) {
this.customer = customer;
}
}
And let's say that two programmers use your class. In that case, these cannot be counted as wrong, yes?
class FirstUserOfCoat{
public static void main(String[] args) {
Coat firstCoat = new Coat();
calculateCoatPrice(firstCoat, 100);
}
public static void calculateCoatPrice(Coat coat, double price){
//if price is public variable,we can set its value like this
coat.price = price * 0.7;
System.out.println(coat.price);
}
}
class SecondUserOfCoat{
public static void main(String[] args) {
Coat secondCoat = new Coat();
calculateCoatPrice(secondCoat,100);
}
public static void calculateCoatPrice(Coat coat, double price){
//if price is public variable,we can set its value like this
coat.price = price * 0.5;
System.out.println(coat.price);
}
}
As you can see, they don’t apply business logic that you define. But when you declare variables as private, and users can access them with only getter and setters, they must only apply your business logic. That is why instance variables have to be private.
Next, let's assume your boss doesn’t want to change the price and customer of the coat, even after creating it with the initial values. In this case, the code would look like this:
public class Coat {
private double price;
private String customer;
public Coat(){
this.price = 100;
this.customer = "student";
}
public double getPrice() {
return price;
}
public String getCustomer() {
return customer;
}
}
Now, the price of every coat is $100 and the customer of every coat is a student. Instance variables are private and there are no setter methods for them. That is why users of Coat
class cannot change the price and customer of the coat. The coat is read-only now.
As in case 1, we can write business logic as we needed in getter and setter methods. At that time, users of the class will only access data that you have defined business logic for.
Lastly, assume that, later, your boss decided that the discount for students will be 30 percent. At that time, you must change the percent in the setter method and your users don’t need any change in their code:
public double getPrice() {
return price;
}
public void setPrice(double price) {
if(customer.equals("student")){
this.price = price * 0.7; //just change 0.8 to 0.7
}else{
this.price = price;
}
}
Hope this is helpful on your next project!
Opinions expressed by DZone contributors are their own.
Comments