Data abstraction is a programming (and design) technique that relies on the separation of interface and implementation.
Let's take one real life example of a TV, which you can turn on and off, change the channel, adjust the volume, and add external components such as speakers, VCRs, and DVD players, BUT you do not know its internal details, that is, you do not know how it receives signals over the air or through a cable, how it translates them, and finally displays them on the screen.
Thus, we can say a television clearly separates its internal implementation from its external interface and you can play with its interfaces like the power button, channel changer, and volume control without having zero knowledge of its internals.
Now, if we talk in terms of C++ Programming, C++ classes provides great level of data abstraction. They provide sufficient public methods to the outside world to play with the functionality of the object and to manipulate object data, i.e., state without actually knowing how class has been implemented internally.
For example, your program can make a call to the sort() function without knowing what algorithm the function actually uses to sort the given values. In fact, the underlying implementation of the sorting functionality could change between releases of the library, and as long as the interface stays the same, your function call will still work.
When code and data are linked together in this fashion, an object is created. In other words, an Object is the device that supports encapsulation.
Within an Object, code, data, or both may be private to that Object. Private code or data is known to and accessible only by another part of the Object. That is private code or data may not be accessed by a piece of the program that exists outside the Object.
When code or data is public, other parts of your program may access it even though it is defined within an Object. Typically, the public parts of an Object are used to provide a controlled interface to the private elements of the object.
For all intents and purposes, an Object is a variable of a user-defined type. Each time you define a new type of Object, you are creating a new data type. Each specific instance of this data type is a compound variable.
A real-world example of polymorphism is a thermostat. No matter what type of furnace your house has (gas, oil, electric, etc.), the thermostat works the same way. In this case, the thermostat (which is the interface) is the same no matter what type of furnace (method) you have. For example, if you want a 70-degree temperature, you set the thermostat to 70 degrees. It doesn't matter what type of furnace actually provides the heat.
This same principle can also apply to programming. For example, you might have a program that defines three different types of stacks. One stack is used for integer values, one for character values, and one for floating-point values. Because of polymorphism, you can define one set of names, push() and pop() , that can be used for all three stacks.
In your program you will create three specific versions of these functions, one for each type of stack, but names of the functions will be the same. The compiler will automatically select the right function based upon the data being stored. Thus, the interface to a stack— the functions push() and pop() —are the same no matter which type of stack is being used. The individual versions of these functions define the specific implementations (methods) for each type of data.
Polymorphism helps reduce complexity by allowing the same interface to be used to access a general class of actions. It is the compiler's job to select the specific action (i.e., method) as it applies to each situation. You, the programmer, don't need to do this selection manually. You need to only remember and utilize the general interface.
The first object-oriented programming languages were interpreters, so polymorphism was, of course, supported at run time. However, C++ is a compiled language. Therefore, in C++, both run-time and compile-time polymorphism are supported.
This is important because it supports the concept of classification. If you think about it, most knowledge is made manageable by hierarchical classifications. For example, a red delicious apple is part of the classification apple, which in turn is part of the fruit class, which is under the larger class food.
Without the use of classifications, each object would have to define explicitly all of its characteristics. However, through the use of classifications, an object need only define those qualities that make it unique within its class. It is the inheritance mechanism that makes it possible for one object to be a specific instance of a more general case. As you will see, inheritance is an important aspect of object-oriented programming.