Objects open up some advantages in how you snap together code that namespaces alone do not.
Code is much easier to deal with when you define abstractions around small sets of functionality and then allow the caller to pass in various objects that provide those functions to the code that needs it.
You can have an application that accepts a 'data_backend', and then provide a data_backend that just stores information into a dict for testing and getting the app initially written, one that tracks all of the changes made or exposes them for tests to check, or another that stores it to sqlite for running a local instance, and another that stores it to some real database for a larger one.
The calling code doesn't need to know what the data_backend does or how it works, it just tells it "store this", "read that" and the data_backend does whatever it does and data goes in and out of it.
You build up all your code that way and you'll be able to easily stub chunks and replace them with functional implementations, and then swap those out when needs change or by options given at runtime.
It's a lot easier to read and write than code that's littered with a million if statements trying to keep track of too much complexity in too many ways all at once.
OOP is just syntax sugar and compiler constraint enforcement for the same kinds of things you see the linux VFS do. There are many filesystems for linux, but each just provides a handful of functions in a structure that should be called against the structures representing the various types of filesystems. In Linux's C you have to slap it all through a (void *), but in languages with objects, you can use those as the medium of abstraction instead of doing it manually.
Some make you do a bunch of inheritance garbage with stapling objects together, others will let you build to interface definitions, or just check the structure of the object to see if it matches the needs of the caller, or be a dynamic language that just checks for the members at runtime.
Code is much easier to deal with when you define abstractions around small sets of functionality and then allow the caller to pass in various objects that provide those functions to the code that needs it.
You can have an application that accepts a 'data_backend', and then provide a data_backend that just stores information into a dict for testing and getting the app initially written, one that tracks all of the changes made or exposes them for tests to check, or another that stores it to sqlite for running a local instance, and another that stores it to some real database for a larger one.
The calling code doesn't need to know what the data_backend does or how it works, it just tells it "store this", "read that" and the data_backend does whatever it does and data goes in and out of it.
You build up all your code that way and you'll be able to easily stub chunks and replace them with functional implementations, and then swap those out when needs change or by options given at runtime.
It's a lot easier to read and write than code that's littered with a million if statements trying to keep track of too much complexity in too many ways all at once.
OOP is just syntax sugar and compiler constraint enforcement for the same kinds of things you see the linux VFS do. There are many filesystems for linux, but each just provides a handful of functions in a structure that should be called against the structures representing the various types of filesystems. In Linux's C you have to slap it all through a (void *), but in languages with objects, you can use those as the medium of abstraction instead of doing it manually.
Some make you do a bunch of inheritance garbage with stapling objects together, others will let you build to interface definitions, or just check the structure of the object to see if it matches the needs of the caller, or be a dynamic language that just checks for the members at runtime.