Только мои 2 цента на вопрос, почему семантика частной видимости в Java - это уровень класса, а не уровня объекта.
Я бы сказал, что ключевым моментом здесь является удобство . Фактически, частная видимость на уровне объекта вынудила бы предоставить методы другим классам (например, в том же пакете) в сценарии, показанном OP.
По правде говоря, я не смог ни придумать, ни найти пример, показывающий, что видимость на уровне частных классов (например, предлагаемая Java) создает какие-либо проблемы по сравнению с видимостью на уровне частных объектов.
Тем не менее, языки программирования с более детальной системой политик видимости могут обеспечить видимость объектов как на уровне объекта, так и на уровне класса.
Например, Eiffel предлагает выборочный экспорт: вы можете экспортировать любую функцию класса в любой класс по вашему выбору, от {NONE} (объектно-частный) до {ANY} (эквивалент общедоступного, а также значение по умолчанию) до {PERSON} (class-private, см. пример OP), для определенных групп классов {PERSON, BANK}.
Также интересно отметить, что в Eiffel вам не нужно делать атрибут закрытым и писать геттер, чтобы предотвратить его присвоение другими классами. Публичные атрибуты в Eiffel по умолчанию доступны в режиме только для чтения, поэтому вам не нужен геттер только для возврата их значения.
Конечно, вам по-прежнему нужен установщик для установки атрибута, но вы можете скрыть его, определив его как «назначитель» для этого атрибута. Это позволяет вам, если хотите, использовать более удобный оператор присваивания вместо вызова установщика.