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.
Let's take a class hierarchy:
class Fruit {
void Eat() {
}
}
class Apple extends Fruit {
}
Obviously, you can use Fruit polymorphically if Eat()
is virtual. But does this make sense? Fruit cannot eat itself!
Should a fruit object rather be passed to a human object which has a Eat()
function?
I am trying to figure out the correct way to think about this. How closely, in general, should programming objects mirror real-life objects?
Abstraction, encapsulation, inheritance, and polymorphism are four of the main principles of object-oriented programming.
There are three major pillars on which object-oriented programming relies: encapsulation, inheritance, and polymorphism.
In object-oriented programming, a class is a blueprint for creating objects (a particular data structure), providing initial values for state (member variables or attributes), and implementations of behavior (member functions or methods).
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.
Simply mirroring real-world objects is rarely a good idea. To borrow from a classic example - software that controls a coffeemaker is not about coffee beans and hot water - it's about making coffee.
You need to find the underlying abstraction to your real-world problem, not just copy nouns into object hierarchies.
If your apple derives from fruit, does it add any interesting behavior? Is the hierarchy really needed? Inheritance adds a level of complexity to your software and anything increasing complexity is bad. Your software is just a bit harder to follow and understand, there's just a bit more to cover in your test and the likelihood of a bug is just a tiny bit larger.
I find OOP is more about the whitespace - what you are leaving out is more important.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With