When I was in college, and for my first few years of Seriour Business Programming Jobs, these four concepts seemed Big And Scary, Like I Would Never Understand Them.
If you work with an object-oriented language, it's worth knowing them intentionally. You can be more effective if you're able to distinguish and apply these with explicit reasons.
It's possible that you use them without realizing it.
Here's when you need an abstraction: If you ever find yourself thinking "I'm writing the same code over and over with only small changes for different types. It would be cool if I could write this routine once and use a more generalized type rather than a {String, Int, Object}|{Cat, Dog, Mouse}{XmlDoc, JSONDoc, BinaryStream}."
When you do so, you're using an Abstraction.
Most objects are complicated enough that you should hide details that the object needs in order to work correctly, but no other objects should ever need. Hide those fields and methods with Encapsulation!
Inheritance is closely related to the concept of Abstraction. It amounts to pushing common features of a class into a base class. Writing the same code over and over again across classes? Make the method once in an Abstract class. Then, in the places where you were repeating code, you can inherit from the base class, getting all the functionality with none of the repetition.
Ever notice how you can add `ints`, `floats`, and `doubles` together? That's polymorphism at work. Polymorphism is the act of different types in a language working with each other because they have a common interface, such as the '+' operator in our example.