Before OOP, there is procedure programming, which basic is divide your program into a set of functions that operates on the data → as your programs grow → spaghetti code
Encapsulation: We group related variables and functions into a unit, we call that uint an object, and refer these variables as properties and these functions as methods. → end up with fewer and fewer parameters for a function, since they all become properties. → easy to use and easy to maintain. → reduce complexity + increase reusability
Abstraction: hiding the implementation and protecting the internal state of an object from being manipulated by external objects. Abstraction helps abstract away the inner workings and present high-level functionalities → simple interface & helps reduce impact of changes → reduce complexity + reduce impact of changes
Inheritance: helps to eliminate redundant code
**Polymorphism: “**poly” means “more”, “morph” means “form”. So Polymorphism means many form:) which allows you to get rid of (refactor) long ugly switch/case statements.