According to Alan Kay, the essential ingredients of OOP are: Message passing, Encapsulation, Dynamic binding.
> OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I’m not aware of them.
* https://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_ka...
* https://medium.com/javascript-scene/the-forgotten-history-of...
* https://softwareengineering.stackexchange.com/questions/4659...
Though it's recognized that Simula invented objects:
At a gig in my college cs lab, teachers talked about OO, 3 teachers, no answer the same.
As a high-level app developer, one has much less use for is-a relationships but what we do sits on top of that well-tread inheritance filled OOP environment.
"The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be."
Typeclasses are a much better way to do polymorphism.
In short, I use OO because everyone else does. Now in my 40s, I’m not going to change merely because another language is more expressive.
But yeah, if I could do it all over again, I’d probably choose Clojure.
OO is a way to bundle a structure with the methods to manage it.
Inheritance is a way to manage the need to customize an object.
Composition is a way to bundle objects.
Why wouldn't you do both? That's what Delphi did back in the 1990s when they built the Visual Component Library. (VCL)
You build your forms in the GUI builder, which composed a form object out of various components which were all eventually derived from tObject. It still lives on, and Lazarus implements something similar for Free Pascal.