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