Encapsulation – Keeping related stuff together and protecting it from unauthorised access. Encapsulation is implemented by creating classes to keep data & behaviour together in one container and by use of access modifiers to protect this data and behaviour from unauthorised access (Public, Protected, Private, Internal). Also keeping related data and behaviour implies “Coherence”.
An obvious analogy is a medicine capsule. Let’s say a disease can be treated by a combination of various simple medicines when all given together. However, some of these constituents may get spoiled if they come in direct contact with Air. The medicine “capsule” encapsulates these related simple medicines into one and restricts access to the delicate ones from exposure to the atmosphere.
Abstraction – Hiding complexity or Hiding unimportant stuff. We are interested in the important methods and data of a class :
– When we are consuming that class and we are not really interested in how that class actually accomplishes or implements methods or its other trivial data and methods
– When we are designing a sub-system and for purpose of simplicity and discussion we want to focus on the important data and methods of a class
Abstraction is implemented by creating Interfaces and Abstract classes. The importance of abstraction is not really apparent when you are working in the same Java package or C# library in which the Interface or Abstract class resides. Our interface or abstract class actually shine when our codebase is a third party library for some other application. This enables us to change the concrete implementation or provide new concrete implementation without causing a breaking change for the consumers of the library.
For example, our library is a set of API for cloud storage. With interfaces, the same set of API can resolve to Azure for a set of consumers and to AWS for a different set of consumers. Or instead, we can use google for both of them without causing a breaking change.