If we do not follow encapsulation in designing a class, future changes will affect user programs. User programs must recompile and retest them completely.
Consider an example "In class we have variable that should be filled with a value by that class user" as shown in the below program.
//Example.java
class Example { int x; }
//Sample.java
class Sample { public static void main(String[] args) { Example e = new Example(); e.x=50; System.out.println(e.x); e.x=-10; System.out.println(e.x); } }
Assume in initial project requirement document customer did not mention that the application should not allow negative numbers to store.So we gave direct access to the variable and user can store any value as shown above.
Assume in future,customer wants application not allows negative numbers.Then we should validate user given value before storing it in the variable.Hence application architecture should as like below.
Declare variable as private, to stop direct access, and define setter method to take value from user. Then user invokes this method to initialize variable.In this method we can validate the passed value before storing it in the variable.If it is <0 we can terminate assignment and informs the same to user, else we will store that data in variable.
Below program shows correct implementation of class by following encapsulation principle with required above validation logic.
//Example.java
class Example { private int x; public void setA(int x) { if(x>0) { this.x=x; } else { System.out.println("do no pass negative number"); } } public int getA() { return x; } }
//Sample.java
class Sample { public static void main(String[] args) { Example e = new Example(); //e.x=50; CE:x has private access in Example //System.out.println(e.x); CE:x has private access in Example e.setA(50); System.out.println(e.getA()); e.setA(-6); System.out.println(e.getA()); } }
Since we have changed the code after application is used by several programmers, every one now should rebuild their application to access variable through setter and getter methods. Otherwise their previous .class file code execution is failed with exception java.lang.IllegalAccessError.
It means since we are not followed encapsulation in developing class it leads lot of maintenance cost.Hence to avoid all these future problems we should always develop classes by following encapsulation principle, even though we do not have any validations before setting and getting variable, it is all required for future sake.
In the above program the variable x we cannot access from Sample class because it is declared as private.
The advantage in designing classes by following encapsulation principle is in future user programs are no need to be recompiled due to code change in setter and getter methods. Ultimately through encapsulation we are hiding implementation details from user.
Consider another example to understand need of encapsulation better, for example bike has 5 gears a method to change gears could reject any value that is less than 1 or greater than 5. If we provide direct access to variable we cannot reject storing a value <1 or >5