91

Although the Internet is filled with lots of definitions for these concepts, they still all sound the same to me. For example, consider the following definitions:

Encapsulation is a process of binding or wrapping the data and the code that operates on the data into a single entity. This keeps the data safe from outside interface and misuse. One way to think about encapsulation is as a protective wrapper that prevents code and data from being arbitrarily accessed by other code defined outside the wrapper.

What I understood from above definition is that creating variables, mark them private and generate getter-setter for those variables and use object to access those getter and setter. In that way data is hidden inside object and is only accessible through object.

Is this correct?


Abstraction is the process in Java which is used to hide certain details and only show the essential features of the object. In other words, it deals with the outside view of an object (interface).

Now this is the part that always confuses me. Whenever I think about abstraction the thing which comes to my mind is Abstract class (maybe because both have Abstract keyword). Above definition says abstraction means hiding data and only showing required details but that is what we are already doing in encapsulation right? then what is the difference. Also I did not get what is outside view of object in "it deals with the outside view of an object".

Can someone please explain this more clearly? Real-life and/or programmatic examples would be especially helpful.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Sandeep Kumar
  • 13,799
  • 21
  • 74
  • 110

3 Answers3

93

OO Abstraction occurs during class level design, with the objective of hiding the implementation complexity of how the the features offered by an API / design / system were implemented, in a sense simplifying the 'interface' to access the underlying implementation.

The process of abstraction can be repeated at increasingly 'higher' levels (layers) of classes, which enables large systems to be built without increasing the complexity of code and understanding at each layer.

For example, a Java developer can make use of the high level features of FileInputStream without concern for how it works (i.e. file handles, file system security checks, memory allocation and buffering will be managed internally, and are hidden from consumers). This allows the implementation of FileInputStream to be changed, and as long as the API (interface) to FileInputStream remains consistent, code built against previous versions will still work.

Similarly, when designing your own classes, you will want to hide internal implementation details from others as far as possible.

In the Booch definition1, OO Encapsulation is achieved through Information Hiding, and specifically around hiding internal data (fields / members representing the state) owned by a class instance, by enforcing access to the internal data in a controlled manner, and preventing direct, external change to these fields, as well as hiding any internal implementation methods of the class (e.g. by making them private).

For example, the fields of a class can be made private by default, and only if external access to these was required, would a get() and/or set() (or Property) be exposed from the class. (In modern day OO languages, fields can be marked as readonly / final / immutable which further restricts change, even within the class).

Example where NO information hiding has been applied (Bad Practice):

class Foo {
   // BAD - NOT Encapsulated - code external to the class can change this field directly
   // Class Foo has no control over the range of values which could be set.
   public int notEncapsulated;
}

Example where field encapsulation has been applied:

class Bar {
   // Improvement - access restricted only to this class
   private int encapsulatedPercentageField;

   // The state of Bar (and its fields) can now be changed in a controlled manner
   public void setEncapsulatedField(int percentageValue) {
      if (percentageValue >= 0 && percentageValue <= 100) {
          encapsulatedPercentageField = percentageValue;
      }
      // else throw ... out of range
   }
}

Example of immutable / constructor-only initialization of a field:

class Baz {
   private final int immutableField;

   public void Baz(int onlyValue) {
      // ... As above, can also check that onlyValue is valid
      immutableField = onlyValue;
   }
   // Further change of `immutableField` outside of the constructor is NOT permitted, even within the same class 
}

Re : Abstraction vs Abstract Class

Abstract classes are classes which promote reuse of commonality between classes, but which themselves cannot directly be instantiated with new() - abstract classes must be subclassed, and only concrete (non abstract) subclasses may be instantiated. Possibly one source of confusion between Abstraction and an abstract class was that in the early days of OO, inheritance was more heavily used to achieve code reuse (e.g. with associated abstract base classes). Nowadays, composition is generally favoured over inheritance, and there are more tools available to achieve abstraction, such as through Interfaces, events / delegates / functions, traits / mixins etc.

Re : Encapsulation vs Information Hiding

The meaning of encapsulation appears to have evolved over time, and in recent times, encapsulation can commonly also used in a more general sense when determining which methods, fields, properties, events etc to bundle into a class.

Quoting Wikipedia:

In the more concrete setting of an object-oriented programming language, the notion is used to mean either an information hiding mechanism, a bundling mechanism, or the combination of the two.

For example, in the statement

I've encapsulated the data access code into its own class

.. the interpretation of encapsulation is roughly equivalent to the Separation of Concerns or the Single Responsibility Principal (the "S" in SOLID), and could arguably be used as a synonym for refactoring.


[1] Once you've seen Booch's encapsulation cat picture you'll never be able to forget encapsulation - p46 of Object Oriented Analysis and Design with Applications, 2nd Ed

StuartLC
  • 104,537
  • 17
  • 209
  • 285
  • so the Java API we use is an abstraction ? – sras Jul 23 '15 at 06:58
  • 1
    Yes, at a high level, an API does provide a simpler abstraction for a consumer to use, blissfully unaware of the underlying complexity behind its internal design. Java is obviously a language, with many associated high level frameworks. However, I believe more specifically, around the time that the OO design [principals terminology](https://en.wikipedia.org/wiki/Object-oriented_design) was coined, that abstraction was more specifically referring to class level design and decomposition, rather than referring to framework or enterprise level design. – StuartLC Jul 23 '15 at 07:23
54

In simple words: You do abstraction when deciding what to implement. You do encapsulation when hiding something that you have implemented.

mbm
  • 945
  • 9
  • 12
37

Abstraction is about identifying commonalities and reducing features that you have to work with at different levels of your code.

e.g. I may have a Vehicle class. A Car would derive from a Vehicle, as would a Motorbike. I can ask each Vehicle for the number of wheels, passengers etc. and that info has been abstracted and identified as common from Cars and Motorbikes.

In my code I can often just deal with Vehicles via common methods go(), stop() etc. When I add a new Vehicle type later (e.g. Scooter) the majority of my code would remain oblivious to this fact, and the implementation of Scooter alone worries about Scooter particularities.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • Can you please provide the code to better explain your answer? – Rahul Gupta Aug 22 '18 at 09:01
  • 1
    @RahulGupta to fully understand this, you need to understand the concept of inheritance. With inheritance you create a hierarchy of classes parents (high level parents are abstract and most child are concerete) and pass down the common traits/properties to the child ones. Abstraction is implemented if done correctly. - Parent classes do the commonalities. (which is hidden from the user perspective if the user is focused on the child) - Child classes focused on being a child. (laymans: as a child, I dont care about my parent's job as possible but I care about is what i do.) – cattarantadoughan Aug 09 '19 at 00:31