I dont understand the concept here...people will say abstraction means hiding the complexity and showing the only the essential feature...
Abstraction isn't about hiding complexity - often it's quite the reverse. Abstraction is taking something specific and making it less specific.
Normally speaking abstracted concepts are more complicated to understand, but once understood do an entire set of things more powerfully that previously you only had specific examples for.
To give you an example, suppose you are building a function which requires some number of strings. Now a colleague of yours might say "I wish to call your function passing an array of strings". Another colleague might say "I wish to call your function passing a List<string>" and another might say "I would like to call it passing a databound list of strings which dynamically gets more strings from our database".
Now you could design your function (let's call it bar) as:
bar(string[] foos) { ... }
bar(List<string> foos) { .. }
bar(DataboundListOfStrings foos) { ... }
Or you could apply abstraction, and say actually you just want a collection of string - you don't particularly care how it's stored. The abstracted form would look something like this:
bar(IEnumerable<string> foos) { ... }
On face value this is more complicated than any single previous case. Rather than just doing foos[i] to get the i-th element out of the array or list, you have do iterate through via the complicated interface - but despite your one function being more complex than a single previous instance, it combines all of the previous implementations into one glorious do-it-all function, which is the essence of abstraction.
I think if you're struggling with the word "abstraction", then perhaps a better word to use is "generalisation", whereby you make something less tied to a specific way of doing something if you don't need to.
Add your 2¢