If you don't have any imagination and you treat dogs as database entries then yes you might do just that. If you are only person writing it and using that code, the same.
You did not address interaction between dogs. Some other idea, how do you pass dogs to a playpen, how would they interact - maybe you want different playpens where you can send your dogs into, some playpens having food, some not having a food, different types of food. What if some other developer will have to write code to heal the dog? If function to dog.Heal() will be in some different module that you never heard of, how do you find it?
You don't want to make each playpen having "if species_of(pet)" code duplication, if pet alone can act on its own will.
Writing code in here seems not that useful here because you would really have to imagine possibilities and see how much code would go into wiring up such a world. Then seeing how having methods in object are helping organize code and in the end prevent whole classes of errors.
Building all of that as an example is just too much work for one off discussion. Just play with imagination of how much complexity you can add to a simple example and soon you will notice.
Well respectfully, you provided the original project spec as an example of where objects were required, and I demonstrated that no, they mostly weren't. I agree that it's unproductive for you to keep adding things to the spec so that I can demonstrate that nope, you still don't need objects to do all that.
All that objects are, are functions glued to data. That's it. Whether or not you choose to glue them together, the behavior of the dog lies in the functions, and the state of the dog lies in the data. Frankly, your examples seem to lead away from objects - how will another developer add the ability to heal dogs, for instance? They can't change the class definition, so they'll have to do something awful like subclass it into HealableDog(), which doesn't interoperate with all the existing dog code at all. Meanwhile, if 'dog' is simply a big ol' struct of data, they can write a function heal(dog) and call it a day.
I highly recommend the first part of this video, which explains the composability problems with objects very well - with dogs and cats even! https://www.youtube.com/watch?v=kc9HwsxE1OY
I would not agree that one cannot change the class definition as it really depends on the system one is writing. I change class definitions on daily basis in business line applications. If I would be making frameworks then maybe I would not do that so often.
Subclass Dog into MyDog, which is exactly the same as Dog. From there, use and modify MyDog as though you would be modifying Dog. Any class that references base class Dog isn't modifiable, but any future work you can use MyDog instances to get all the functionality you need (with some ugly casting). There are other solutions as well.
You did not address interaction between dogs. Some other idea, how do you pass dogs to a playpen, how would they interact - maybe you want different playpens where you can send your dogs into, some playpens having food, some not having a food, different types of food. What if some other developer will have to write code to heal the dog? If function to dog.Heal() will be in some different module that you never heard of, how do you find it?
You don't want to make each playpen having "if species_of(pet)" code duplication, if pet alone can act on its own will.
Writing code in here seems not that useful here because you would really have to imagine possibilities and see how much code would go into wiring up such a world. Then seeing how having methods in object are helping organize code and in the end prevent whole classes of errors.
Building all of that as an example is just too much work for one off discussion. Just play with imagination of how much complexity you can add to a simple example and soon you will notice.