I and one guy have been discussing potential solution of a problem on an unrelated board, regarding the typical getter/setter hate, ie. using getters/setters leads to procedural programming.I presented the attached solution as a representation of encapsulation and the TellDontAsk principles, which he said was not OO enough, because it persumably:has methods returning a value of an attributehas methods mutating attributesThis is the code:interface AnimalWithCollar{    /**     * Adds new collar to the animal.     *     * @param Collar $collar     *     * @throws InvalidArgumentException When the collar you are trying to add already has an owner differentiating from     *                                  from the animal you are trying to add the collar to.     */    public function addCollar(Collar $collar);    /**     * Checks, whether the animal has a collar.     *     * @return bool     */    public function hasCollar();}interface ItemForFetching{    /**     * Checks, whether the animal passed as the first parameter can carry the item.     *     * @param AnimalThatCanFetch $animal     *     * @return bool     */    public function animalCanCarryIt(AnimalThatCanFetch $animal);}class Stick implements ItemForFetching{    /** @var int */    protected $_weight;    /**     * @param int $weightOfTheItem     */    public function __construct($weightOfTheItem)    {        $this->_weight = $weightOfTheItem;    }    /**     * @inheritdoc     * @see ItemForFetching::animalCanCarryIt     */    public function animalCanCarryIt(AnimalThatCanFetch $animal)    {        return $animal->canCarryAnItemWeighting($this->_weight);    }}interface AnimalThatCanFetch extends AnimalWithCollar{    /**     * Fetches the item passed as the first parameter.     *     * @param ItemForFetching $item     *     * @throws InvalidArgumentException When the animal is unable to fetch the item, because it is too heavy.     */    public function fetch(ItemForFetching $item);    /**     * Checks, whether the animal can carry an item of said weight.     *     * @param int $weight     *     * @return bool     */    public function canCarryAnItemWeighting($weight);}class Dog implements AnimalThatCanFetch{    /** @var Collar[] */    protected $_collars;    /**     * @inheritdoc     * @see AnimalWithCollar::addCollar     */    public function addCollar(Collar $collar)    {        $collar->assignOwner($this);        $this->_collars[] = $collar;    }    /**     * @inheritdoc     * @see AnimalWithCollar::hasCollar     */    public function hasCollar()    {        return (count($this->_collars) > 0);    }    /**     * @inheritdoc     * @see AnimalThatCanFetch::fetch     */    public function fetch(ItemForFetching $item)    {        if ($item->animalCanCarryIt($this) == false)        {            throw new InvalidArgumentException('The item is too heavy. The animal cannot fetch it.');        }        // process the fetching logic    }    /**     * @inheritdoc     * @see AnimalThatCanFetch::canCarryAnItemWeighting     */    public function canCarryAnItemWeighting($weight)    {        return $weight <= 5; // indicating it may carry an item up to 5 kg    }}class Collar{    /** @var int */    protected $_diameter;    /** @var string */    protected $_color;    /** @var AnimalWithCollar */    protected $_owner;    /**     * @param int $diameter     * @param string $color     */    public function __construct($diameter, $color)    {        $this->_diameter = $diameter;        $this->_color = $color;        $this->_owner = null;    }    /**     * @param AnimalWithCollar $newOwner     *     * @throws InvalidArgumentException When the collar is already owned by a different animal than the one passed.     */    public function assignOwner(AnimalWithCollar $newOwner)    {        if ($this->hasOwner() && $this->belongsTo($newOwner) == false)        {            throw new InvalidArgumentException('The collar may have only one owner.');        }        $this->_owner = $newOwner;        $newOwner->addCollar($this);    }    /**     * @param AnimalWithCollar $animal     * @return bool     */    public function belongsTo(AnimalWithCollar $animal)    {        return $this->_owner == $animal;    }    /**     * @return bool     */    public function hasOwner()    {        return $this->_owner != null;    }}Amount of interfaces, naming conventions aside, is there a way this design could be even more object oriented than it already is?
Does my code still break encapsulation and uses getters/setters instead of the TellDontAsk principle?
php;object oriented