Let me explain it with an example. Let's say you have a ExamResult class and it has a method passed(), which returns a true or false depending on whether the user has passed the exam or not. Something like this:
Code: Select all
class ExamResult{
public int marksScored;
public boolean passed(){
return marksScored>50; //pass if marksScored is >50.
}
}
In the above code, the abstraction is passed/failed and you are representing that abstraction through the marksScored variable. However,
observe that marksScored is public. Therefore, any user of this class can start relying on the marksScored field, because it is accessible to all, instead of passed() method.
Later on, you decide to use Grades (A B C D and F) instead of marks as the choice of representation and want to change passed() method code to: return !'F'.equals(grade)?
But other user's code will now fail to compile because they are depending on the marksScored field to be present in the ExamResult class. They were not really supposed to use this field. They should have used the passed() method. But you didn't make that field private, so, they found it and used it anyway. Had you made marksScored as private (i.e. made the class encapsulated), they would not have used this field and their logic based on passed() method would still work even if you change marksScored to grade.
Thus encapsulating a class properly prevents this breakage from happening.