Object-oriented – Why is Encapsulation considered a primary principle in OOP

abstractionencapsulationobject-orientedprinciples

I am currently trying to understand more deeply the 4 principles of OOP: Abstraction, Encapsulation, Inheritance, and Polymorphism.

After studying the four principles, I don't fully understand why Encapsulation is considered one of the four primary principles of OOP.

Encapsulation is extremely common and useful in OOP, but it seems to me as more of a technique or strategy to use as part of Abstraction.

A good definition for Abstraction:

'Abstraction is the concept of moving the focus from the details and concrete implementation of things, to the types (i.e. classes), the operations available (i.e. methods), etc, thus making the programming simpler, more general, and more abstract.'

Encapsulation, on the other hand, is this:

'Hiding the internal implementation details of a class from the outside software world, and prividing an interface for other software entities to communicate and manipulate that class.`

If so, it seems to me that Encapsulation is mostly a technique to make things more abstract in the software system. Thus, it acts more of a strategy that implements the concept of Abstraction, rather than a primary principle by itself. It could be considered a 'principle' and not only a technique, but it still would be a part of the more general Abstraction principle, and not a major principle by itself.

Does anybody agree? If I'm wrong, please explain why.

Best Answer

I agree, those descriptions are really similar. But Abstraction is the idea of consolidating state and functionality into meaningful bundles. Encapsulation is about protecting that bundle so that an outsider can't come in, break the rules, and mess with your state.

  • The abstraction has exclusive domain over the state, and encapsulation is how we guarantee that.

Another side of encapsulation is that the implementation may be more complicated than the abstraction. So you might have a method (pseudocode):

List<Thing> getRelatedThings()

but internally, the list of Things isn't represented as a List at all. Maybe it's a complicated mess of data structures, from which you abstract a List.

Or maybe it is just a list of Things, but you want to be able to change your mind later. The abstraction stays the same, but encapsulation protects the implementation.

  • So another difference would be: abstraction strives to simplify, but encapsulation hides complication.

EDIT: one more thing... Encapsulation is an important aspect of decoupling. So let's say that I have two classes that are really similar. Without encapsulation, those abstractions might start to overlap and become more and more inter-twined over time. Encapsulation says, no, this abstraction is distinct from that abstraction.

If there is a common abstraction, factor it out & abstract a base class.

(although now you have two problems ;) ) (...sorry, thats a "favor composition over inheritance" joke. If that doesn't make sense, you'll get there.)

  • encapsulation keeps the boundaries of an abstraction distinct