Encapsulation and Data Abstraction in Java

As we know that Encapsulation facilitates Data Abstraction, which is the relationship between a class and its datamembers. Encapsulation refers to the fact that the data variables (i.e. properties) and the methods (i.e behaviors) are encapsulated together inside a template called a class. The data members encapsulated inside a class may be declared public, private, or protected. However, good object-oriented programming practice requires tight encapsulation. That means all data members of the class should be declared private. That is, the code outside of the class in which the data members are declared can access them only through method (getter and setter), and not directly. This is called data abstraction (or data hiding), because now the data is hidden from the user, and the user can have access to it only through the methods.

Encapsulation (and data abstraction) makes the code more reliable, robust, and reusable. This is so because the data and the operations on it (methods) are encapsulated into one entity (the class), and the data member itself and the access to it are separated from each other (tight encapsulation or data abstraction). For example, in tight encapsulation, where your data members are private, if you change the name of a data variable, the access code will still work as long as you don’t change the name of the parameters of the method that is used to access it.

Consider the below code example:

1. public class TestEncapsulateBad {
2.     public static void main(String[] args) {
3.            EncapsulateBad eb = new EncapsulateBad();
4.            System.out.println("Do you have a headache? " + eb.headache);
5.     }

6. }
7. class EncapsulateBad {
8.     public boolean headache = true;
9.            public int doses = 0;
10.    }

The output from this code follows: 

    Do you have a headache? true 

Note that in line 4, the data variable of class EncapsulateBad is accessed directly by the code piece eb.headache. This is only possible because the variable headache is declared public in the class EncapsulateBad. If you declare this variable private, line 4 will cause a compiler error. Let’s say you keep it public, and then you change the name of the variable headache in the EncapsulateBad class to something else. In this case, line 4 will again generate an error, because you need to change the name of the variable headache in line 4 to the new name as well.

However, a better solution is to separate the data variable from the access by declaring it private and provide access to it through methods, as shown in code Listing below. 

1. public class TestEncapsulateGood {

2.     public static void main(String[] args) {
3.            EncapsulateGood eg = new EncapsulateGood();
4.            eg.setHeadache(false);
5.            System.out.println("Do you have a headache? " + eg.getHeadache());
6.     }
7. }

8. class EncapsulateGood {
9.    private boolean headache = true;
10.   private int doses = 0;

11.   public void setHeadache(boolean isHeadache){
12.    this.headache = isHeadache;
13.   }

14.   public boolean getHeadache( ){
15.    return headache;
16.   }
17. }

The output from this code follows:

    Do you have a headache? false 

Note that the variable headache is now declared private (line 9), and it can be accessed through methods setHeadache(…) and getHeadache(), which are declared public (lines 11 and 14). The world can still access your data, but this access process is separated from the details of the data—the data variable name, how the change is made to it, and so forth. This hiding of the data details from the access procedure is called data abstraction. In an application, it means you can make changes to the data variables in your class without breaking the API. Such protection also makes the code more extendible and easier to maintain. So, the benefits of encapsulation are: hard-to-break reliable code, easy maintenance, and extensibility. 

Remember that The has-a relationship is associated with encapsulation, whereas the is-a relationship is associated with inheritance. 

So, encapsulation determines how the classes interact with each other, a property also called coupling. Actually, there are two more characteristics that good object-oriented programming should exhibit: loose coupling and cohesion

You can read more about  Coupling and Cohession.

Reference(s): SCJP Exam for J2SE 5

No comments:

Post a Comment