В пхп классо-ориентированный дизайн —потому "внутри класса" доступно даже приватное состояние другого объекта, если у него тот же тип. То есть инкапсуляция в «схеме» объекта — в классе, а не у самого объекта
Пример:
class Bro {
public function __construct(
private string $name,
){}
public function changeBro(Bro $bro) {
$bro->name = 'я думал ты бро, а ты не бро';
}
}
$maks = new Bro('Макс');
$roma = new Bro('Рома');
$roma->changeBro($maks);
// теперь у Макса имя другое :)
такая архитектура языка, объекты разные, а доступ есть
К слову, это удобная фича… можно сравнить с видимостью в контексте одного package в го :)
Ну а касательно иерархии типов вам выше накинули — ребёнок всегда является корректным родительским типом, это называю ковариативностью. Любой тигр — кошачьи, а кошачьи — животное, всегда — согласно иерархии типов