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.
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.