While some objects I create are modelling real world objects, would not pre-OOP code do the same?
The greatest difference between OOP and pre-OOP code is that the former models a real world situation as a group of distinct entities interacting with each other, each with limited "power" regarding what it can do, and also capable of "reacting" to external events with actions of its own. The latter models everything as a big chunk of data that doesn't do anything on its own, while the computation represents "things that happen" and can affect any or all of them.
Whether it better models the real world or not, that really depends on which facets of the world you're modelling. A physics simulation, for example, where you want to describe the effects that, say, a fire being lit would have in the surrouding objects, would be better represented by a "traditional" approach, since both the light and the heat are well-defined processes that affect both external and internal state of other objects, and do not vary according to the behavior of each particular object, only being affected by their properties.
On the other hand, if you're modelling different components that interact to produce the desired behavior, treating them as agents instead of passive things can make it easier to do it correctly without missing anything. If I wanna turn on my TV, I just press the button, if the power cord is unplugged the TV.turnOn
will check that for me. So, there's no risk of turning a cog and forgetting to turn that other that's touching it, since the cog itself (if programmed correctly) will take care of the secondary interactions that come as a consequence of the primary one.
But OO is really about how to model things, and that method of modelling doesn't seem inspired by the real world to me.
I believe it has more to do with the way we perceive the world than how the world actually is. One could argue that everything is just a bunch of atoms (or energy, or waves, whatever), but that doesn't help us handle the task of dealing with the problems we face, with understanding the environment around us and predicting future events (or describing past ones). So we make "mental models" of the world, and often those mental models find a better correspondence with OO than the data+processes one - which arguably models "better" how the real world actually operates.
It's also interesting to note that most people think of OOP as synonym with "classic OOP", where we taxonomically create sets and subsets of things, and unambiguously put objects in a very specific set. That's very useful for creating reusable new types, but not so great when the entity you're modelling is pretty much self-contained, and while it initiates interactions with other objects it rarely, if ever, is the target of an interaction. Or worse, when there are few (maybe only one) instance of that entiy, or the instances vary wildly in composition, behavior or both.
However, there's also "prototypical OOP", where an object is described by picking a similar one and enumerating the aspects where they differ. I'd suggest this essay for a good and not-too-technical explanation of the thought process (the whole post is too big, even for Steve Yegge's standards, so I'm pointing to the relevant section :P). Again, this is a good match for our mental models when imagining unknown instances by comparison to a known one, but not necessarily for how the real world "works"... (two cows are actually completely distict entities, even if we perceive them as being "alike" in many ways)
modeling the real world
may not be what really sets OO apart. May be. But i definitely wont believe that you will fail doing this in OO either. Which paradigm or technique do you think makes it better than OO?