The four principles of OOP (Object-Oriented Programming) are, in order of my favorites: inheritance, abstraction, polymorphism, encapsulation. Don’t get me wrong though, I love all four of them. In my final semester of college, I took a class on OOP in PHP and I loved it so much that I accidentally did the final project halfway through the semester before I even knew what the project was (it was to refactor a previous assignment with OOP).
I just love how reusable and readable these principles and their implementations make code. I love inheritance because I can reuse code from similar classes by putting it in a parent class and creating child classes based off it (and being able to do this multiple times is 👌). In my hobbyist game dev projects, I’ve used this to simplify anything from platform types to UI panels. Inheritance is not only cool because every child class inherits the same attributes and methods, but principles like abstraction and polymorphism allow us to override or mutate the methods (as well as add our own unique ones of course)
With inheritance, if we need to change a shared method or add a new attribute to all child classes, we only have to change the parent class and the changes are inherited by the children.
Abstraction is really nice because it just means that other objects don’t need to know how a method works, they just need to know that an object has it and know what type it returns (if any). You just create the method name, pick the arguments (if necessary) and make it public. That’s all that other objects need to know: method name, arguments and return type. Abstraction also builds off the principle of encapsulation, which is a principle meaning that objects should manage their own “state” (attributes) and control how other objects are allowed to interact with them (methods). For example by making their attributes private (can only be seen by the object) and creating accessor and mutator methods visible to other objects. Methods can also be made private or protected if they shouldn’t be accessed by other objects. This keeps code nice and tidy and helps prevent an object accidentally messing up another object.
Finally, polymorphism allows us to have multiple methods (including constructors) of the same name that take different arguments. The object automatically runs the method that corresponds to the given arguments. This is also great for simplifying code as you don’t have to create and remember multiple names for methods that could have the same name. It’s especially useful for making multiple constructors that take various sets of arguments.