Saturday, 8 July 2017

Difference between Abstraction and Encapsulation in Java - OOP

Both Abstraction and Encapsulation are two of the four basic OOP concepts which allow you to model real-world things into objects so that you can implement them in your program and code. Many beginners get confused between Abstraction and Encapsulation because they both look very similar. If you ask someone what is Abstraction, he will tell that it's an OOP concept which focuses on relevant information by hiding unnecessary detail, and when you ask about Encapsulation, many will tell that it's another OOP concept which hides data from outside world. The definitions are not wrong as both Abstraction and Encapsulation does hide something, but the key difference is on intent.

Abstraction hides complexity by giving you a more abstract picture, a sort of 10,000 feet view, while Encapsulation hides internal working so that you can change it later. In other words, Abstraction hides details at the design level, while Encapsulation hides details at the implementation level.

For example, when you first describe an object, you talk in more abstract term e.g. a Vehicle which can move, you don't tell how Vehicle will move, whether it will move by using tires or it will fly or it will sell. It just moves. This is called Abstraction. We are talking about a most essential thing, which is moving, rather than focusing on details like moving in plane, sky, or water.

There are also the different levels of Abstraction and it's good practice that classes should interact with other classes with the same level of abstraction or higher level of abstraction. As you increase the level of Abstraction, things start getting simpler and simpler because you leave out details.

On the other hand, Encapsulation is all about implementation. Its sole purpose is to hide internal working of objects from outside world so that you can change it later without impacting outside clients.

For example, we have a HashMap which allows you to store the object using put() method and retrieve the object using the get() method. How HashMap implements this method  is an internal detail of HashMap, the client only cares that put stores the object and get return it back, they are not concerned whether HashMap is using an array, how it is resolving the collision, whether it is using linked list or binary tree to store object landing on same bucket etc.

Because of Encapsulation, you can change the internal implementation of HashMap with ease without impacting clients who are using HashMap. For example, in Java 8, the java.util.HashMap changes its implementation to use a binary tree instead of LinkedList to store objects in the same bucket after a certain threshold.

The client doesn't need to make any change to benefit from this code change because those details are not exposed to them. Had client knows about that i.e. somehow they can get the reference of the internal array from HashMap, it would not have been possible to change the implementation without impacting clients.

There are many design principles which are based on Abstraction e.g. "coding for interfaces then implementation" which helps you to write flexible code in Java or C++. The idea is that a class depend upon on an interface, a higher level of abstraction than the class, a lower level of abstraction. This result in flexible code which can work with any implementation of the interface.

For example, if you need HashMap, your class should depend upon Map instead of HashMap. Similarly, if you need ArrayList, make sure you should use the List. Thankfully, Uncle Bob has shared several such design principles on Clean Code, collectively known as SOLID design principles, which is something every OOP programmer must learn and understand.

Difference between Abstraction vs Encapsulation


Here are some of the key difference between Encapsulation and Abstraction in point format for your quick revision:

1) The most important difference between Abstraction and Encapsulation is that Abstraction solves the problem at design level while Encapsulation solves it implementation level.

2) Abstraction is about hiding unwanted details while giving out most essential details, while Encapsulation means hiding the code and data into a single unit e.g. class or method to protect inner working of an object from outside world. In other words, Abstraction means extracting common details or generalizing things.

3) Abstraction lets you focus on what the object does instead of how it does, while Encapsulation means hiding the internal details of how an object works. When you keep internal working details private, you can change it later with a better method. The Head First Object Oriented Analysis and Design has some excellent examples of these OOP concepts, I suggest you read that book at least once to revisit OOP fundamentals.

4) Abstraction focus on outer lookout e.g. moving of vehicle while Encapsulation focuses on internal working or inner lookout e.g. how exactly the vehicle moves.

5) In Java, Abstraction is supported using interface and abstract class while Encapsulation is supported using access modifiers e.g. public, private and protected.

Here is a nice table highlighting key differences between Abstraction and Encapsulation in Object Oriented Programming:

Oracle Java, Abstraction, Encapsulation, Oracle Java Certifications, Oracle Java Materials, Oracle Java Guide

That's all about the difference between Abstraction and Encapsulation in Java and OOP. I understand, they both seems very similar but as I said they are a totally different concept. Just remember that Abstraction solves the problem at design level while Encapsulation solves at the implementation level. Both are very important for an OOP programmer but sometimes it can be difficult to explain.