I am trying to wrap my head around object oriented programming.
My understanding is that we have objects so we can design our programs to mirror real-life objects.
My understanding is that we have objects so we can design our programs to mirror real-life objects.
Maybe more like 'relate' them to real life objects, where applicable.
Should a fruit object rather be passed to a human object which has a Eat() function?
Yes, or something more general than a human.
I am trying to figure out the correct way to think about this. How closely, in general, should programming objects mirror real-life objects.
Only define what you need to define. Then the implementation (typically) becomes very obvious. In other words, you're probably thinking too hard.
Something of class Herbivore would have an Eat function, as would something of class Carnivore, but each one's Eat would have some differing restrictions on what argument could be passed to the Eat function. The Fruit is what is eaten, so it would be passed as the argument to Herbivore.Eat(), whereas you would want to pass an object of type Hamburger to Carnivore.Eat(), and raise an exception if Hamburger were passed to Herbivore.Eat().
But really, I don't think OOP is so we can model software objects to be just like real-life objects. I've found that most of my OOP design works with pretty abstract objects, and only with respect to the system they are part of. If I wrote a library checkin/checkout system, I would model a Book in terms of its administrative properties and functions - I would not model it as a collection of Page objects, and I doubt I would even define anything like a Read() method, although such is the main purpose of having a book in the first place. The Book object's role in the system dictates my design much more than what one does with books in the real world.
You're correct that probably eat() would be a method of a human or mammal or fruitFly. A fruit itself probably has no behaviour, and hence no methods.
I don't often consider the benefits of OO in realtion to the mapping from real things to Object. That's probably because we deal with less tangible concepts such as Invoices and Orders.
I see the primary win from OO to be in the structure it brings to my code. In the real world Invoices and Orders don't actually do anything, but in my code they do. So the programmtic Order may well be much closer to the combination of the data representing an order, and some human business process relevent to the order.
I tend to think about:
Is a
Has a
So, an apple is a fruit, so inheritance makes sense.
But, fruit has (is) eatable may make sense, but that shows it is a property of fruit, not an action (method).
For example, you may have unripened apple, that would not be edible (eatable) so you could then set this property.
Now, whatever is going to eat this you could set whether an apple is part of it's diet.
Now Has a
would be for composition. So, an apple has a seed would mean that seed doesn't extend apple, but an apple would have a collection of seeds.
So, you do have a design problem, and I hope that these two concepts may help to clarify.
I think you should read the SOLID principles, it's going to help you a lot. http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx
You've got a design problem -- as you correctly point out, Eat() doesn't make obvious sense as a member of Fruit. On the other hand, an "edible" attribute would make more sense. As would an "onEaten" event, etc. What your fruit/apple classes expose (and what other objects make sense in your model) depends on a lot of other factors, including what you're trying to accomplish with those constructs in your application.
In general you want your classes to represent logical domain level entities. Sometimes those correspond to a physical entity in the real world, but in many cases they don't.
In my opinion OO problem decomposition is something programmers are generally pretty bad at. I don't know how many times I've seen the equivalent of a car derived from a steering wheel and shaken my head while the original developer couldn't wrap their head around why their design didn't make a lot of sense.