4

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.

Aviv Cohn
  • 21,190
  • 31
  • 118
  • 178
  • 3
    Keep in mind that these "4 principles" are arbitrary: the guy who coined OO didn't come up with them, they are not principles in formal studies either. Whoever wrote them down is accounted for his (mis)interpretations of OO. – Thiago Silva Feb 27 '14 at 12:55

4 Answers4

5

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
sea-rob
  • 6,841
  • 1
  • 24
  • 47
  • 1
    I agree. I would like to summarize it like this: the key and main difference is Abstraction referring to simplification or simplicity and Encapsulation to protection. – Lucia Pasarin Feb 27 '14 at 00:57
  • 2
    Another summarization is that Abstraction is the "carrot" to suggest that people should do OOP, and Encapsulation is the "stick" to make sure that any dissidents don't get any creative ideas to subvert OOP to solve a problem "just this once." I can't count the number of times an implementation detail became part of the design because someone wanted to solve "just one problem" real quick for a customer. – Cort Ammon Feb 27 '14 at 02:41
2

I agree, encapsulation is more of a mechanism than a principle. The same could be said about implementation inheritance, which is an (arguably dangerous) mechanism for achieving subtyping, which is in turn just one kind of Polymorphism. Honestly, I wouldn't consider inheritance a fundamental principle of OOP at all - objects are about interfaces, not inheritance trees.

On that note, you say "the four principles" as if there were an authoritative source for them; I don't believe there is one. OOP means many things to many people. Personally, I find the SOLID principles to be useful, but understand that regardless of which ones you subscribe to, they're just a means to an end. I'd argue nothing matters more than correctness, modularity, and clarity, in that order.

Doval
  • 15,347
  • 3
  • 43
  • 58
  • agree -- was kind of surprised to see inheritance in the list. And polymorphism seems more like a logical consequence rather than a core principle. – sea-rob Feb 26 '14 at 21:38
2

OOP was commonly defined as encapsulation, inheritance, and polymorphism. I've seen this definition around a lot, and I've only seen abstraction, encapsulation, inheritance, and polymorphism, a few times. Matt Weisfeld's 'The Object-Oriented Thought Process' acknowledges the 3 part definition and goes on to add composition to the end of the list.

Although nobody agrees on what OO is, there are a lot of definitions.

I think what happened is that encapsulation/inheritance/polymorphism was originally set up as a definition for what OO is, then later people referred to the individual points as principles, then people stopped referring to the whole thing as a definition, and instead referred to them as a set of principles, then people noticed that while inheritance is how the principle of polymorphism was implemented in OOP, there was no principle listed to correspond to encapsulation as an implementation, so they added it. Then you noticed that not all of these principles are on the same level of abstraction. I don't have any proof that it happened in that order, but we do know what the start and endpoints were.

If you take the 4 "principles" as a definition, but then throw out encapsulation and inheritance as implementations, you get abstraction+polymorphism as a definition of OOP, which is ridiculous, since many languages that have no objects in them at all have both of those.

Michael Shaw
  • 5,116
  • 1
  • 21
  • 27
  • I do consider encapsulaton+polymorphism a better definition of OOP. abstraction is great, but nothing to do with OOP, you could say that structured code is a requirement too. – Javier Feb 27 '14 at 02:14
  • @Javier May be a newbie question, but what do you mean by 'structured code'? If you mean a software with a clear and well-written architecture, than any good software in *any language, not only OOP* should have this, am I right? If so, than why would you consider it a primary OOP principle? Also, why wouldn't you consider inheritance a primary principle? Yes, it's not exactly on the same abstraction level as polymorphism, but it is (correct me if I'm wrong) a significant characteristic of code written in OOP, am I wrong? – Aviv Cohn Feb 27 '14 at 06:41
  • "Structured Programming" has a specific meaning. First came machine code written directly in hex or octal. Then assembly with memnonics for machine code. Then symbolic languages. But they just used jumps and gotos to control program flow. "Structured Programming" came along and introduced procedures, and it changed everything. However, the procedures were global, so a very weak sense of encapsulation. Today "structured" is kind of derogatory (justifiably), because it means programming that's neither here nor there -- neither OO nor Functional, just kind of a throwback. – sea-rob Feb 27 '14 at 07:38
  • However, you are right -- you can do OO in a structured language, and lots of people do structured programming in OO languages ;). You can do Functional in either. Or OO in functional. It's just a matter of how hard the language makes it. Haskell is the only one that no one else can do. :P – sea-rob Feb 27 '14 at 07:39
  • @Javier I take for granted that Abstraction means abstracting data and methods together, or state and messages. With that understanding it moves it into the OO realm. I agree with you, though -- even machine code is a kind of abstraction. – sea-rob Feb 27 '14 at 07:45
  • @RobY: A couple of nitpicks: not all procedures were global, I think a good argument could be made that (WRT code, if not data) structured programming was pretty good with encapsulation (especially considering its competition), and procedures already existed. – Michael Shaw Feb 27 '14 at 08:50
  • @Prog: The good parts of structured programming (spaghetti code using gotos = evil, code should be logically structured) have been absorbed into programming culture; the bad parts (dogmatic insistence on one entrance/one exit to/from a function, dogmatic resistance to gotos even in the (rare) instances where they're the right tool for the job) have been forgotten. – Michael Shaw Feb 27 '14 at 09:05
1

You need both a level of abstraction and the principle of encapsulation in order to think about objects as the primary units in the system.

Before OO the primary unit was functions that manipulated data. This was itself an abstraction above machine code which was operations acting on data. The principle of abstraction in the context of OO basically says stop thinking about functions and start thinking about units of collected behavior like we have in the real world (which leads to objects).

Encapsulation says that these units of collected behavior must be solely responsible for their own behavior and must stop other units of behavior from interfering with that (which again leads to objects).

So you really need both abstraction and encapsulation to get to objects, given that objects are distinct units of behavior that take responsibility for their own behavior.

It is possible to imagine a system where you have distinct units of common behavior but that these proto-objects have no restriction on other proto-objects going in and messing around the behavior. In fact that describes most badly designed OO software, full of getters and setters and exposed private methods.

Without encapsulation you don't have "objects" as people like Kay imagined, so abstraction to units of behavior is not enough.

Cormac Mulhall
  • 5,032
  • 2
  • 19
  • 19