it-swarm.com.ru

Доступ к приватному полю другого объекта в том же классе

class Person 
{
   private BankAccount account;

   Person(BankAccount account)
   {
      this.account = account;
   }

   public Person someMethod(Person person)
   {
     //Why accessing private field is possible?

     BankAccount a = person.account;
   }
}

Пожалуйста, забудьте о дизайне. Я знаю, что OOP указывает, что частные объекты являются частными для класса. У меня вопрос: почему OOP был спроектирован так, что частные поля имеют доступ на уровне класса и не доступ на уровне объекта

68
Nageswaran

Мне также немного любопытно с ответом. 

Самый удовлетворительный ответ, который я нахожу, от Артемикса в другом посте здесь (я переименовываю AClass в класс Person): Почему вместо уровня объекта используются модификаторы доступа на уровне класса?

Частный модификатор применяет принцип инкапсуляции.

Идея состоит в том, что «внешний мир» не должен вносить изменения во внутренние процессы Person, потому что реализация Person может со временем меняться (и вам придется изменить весь внешний мир, чтобы исправить различия в реализации - что почти невозможно).

Когда экземпляр Person обращается к внутренним объектам другого экземпляра Person, вы можете быть уверены, что оба экземпляра всегда знают детали реализации Person. Если логика внутренних процессов к Человеку изменилась - все, что вам нужно сделать, это изменить код человека.

Правка: Пожалуйста, подтвердите ответ Артемикс. Я просто копирую это.

48
Iwan Satria

См. Спецификация языка Java, раздел 6.6.1. Определение доступности

Говорится

В противном случае, если член или конструктор объявлен private, тогда доступ разрешен, если и только если это происходит в теле класс верхнего уровня (§7.6), который включает в себя объявление члена или конструктор.

Нажмите на ссылку выше для более подробной информации. Так что ответ таков: Джеймс Гослинг и другие авторы Java решили, что так и будет.

15
jlordo

Хороший вопрос. Похоже, что модификатор доступа на уровне объекта обеспечит применение принципа инкапсуляции еще дальше.

Но на самом деле все наоборот. Давайте возьмем пример. Предположим, вы хотите глубоко копировать объект в конструкторе, если вы не можете получить доступ к закрытым членам этого объекта. Тогда единственный возможный способ - добавить некоторые общедоступные методы доступа ко всем частным участникам. Это сделает ваши объекты голые для всех других частей системы.

Таким образом, инкапсуляция не означает быть закрытой для всего остального мира. Это значит быть избирательным в отношении того, с кем вы хотите быть открытым.

7
Wei Qiu

Это работает, потому что вы находитесь в class Person - классу разрешено тыкать в его собственный тип класса. Это действительно помогает, когда вы хотите написать конструктор копирования, например:

class A
{
   private:
      int x;
      int y;
   public:
      A(int a, int b) x(a), y(b) {}
      A(A a) { x = a.x; y = y.x; }
};

Или, если мы хотим написать operator+ и operator- для нашего класса больших чисел. 

2
Mats Petersson

Просто мои 2 цента на вопрос, почему семантика приватной видимости в Java является уровнем класса, а не уровнем объекта. 

Я бы сказал, что удобство кажется ключевым здесь. Фактически, частная видимость на уровне объекта вынудила бы предоставить методы другим классам (например, в том же пакете) в сценарии, проиллюстрированном OP.

По правде говоря, я не смог ни придумать, ни найти пример, показывающий, что видимость на уровне частного класса (например, предлагаемого Java) создает какие-либо проблемы по сравнению с видимостью на уровне частного объекта. 

При этом языки программирования с более тонкой системой политик видимости могут обеспечивать как видимость объекта на уровне объекта, так и на уровне класса.

Например, Eiffel , предлагает выборочный экспорт: вы можете экспортировать любой объект класса в любой класс по вашему выбору, от {NONE} (object-private) до {ANY} (эквивалент public, а также по умолчанию), {PERSON} (закрытый класс, см. пример OP), определенным группам классов {PERSON, BANK}.

Также интересно отметить, что в Eiffel вам не нужно делать атрибут закрытым и писать метод получения, чтобы другие классы не могли его присвоить. Открытые атрибуты в Eiffel по умолчанию доступны в режиме только для чтения, поэтому вам не нужен геттер, чтобы просто вернуть их значение. 

Конечно, вам все еще нужен установщик для установки атрибута, но вы можете скрыть его, определив его как «присваиватель» для этого атрибута. Это позволяет вам, если вы хотите, использовать более удобный оператор присваивания вместо вызова сеттера.

0
Temp Agilist

Первое, что мы должны здесь понять, это то, что все, что нам нужно сделать, - это следовать принципам упс, поэтому инкапсуляция означает, что оборачивает данные внутри пакета (то есть класса), а затем представляет все данные как объект и легко доступен. так что если мы сделаем поле не частным, чем оно будет доступно индивидуально. и это приводит к плохой паратифе.

0
Sachin Jadhav

Поскольку private модификатор доступа делает его видимым только внутри класса . Этот метод все еще в классе .

0
darijan

С отражением концепции в Java возможно модифицировать поля и методы приват

Модифицированные методы и учебные заведения с Refleccion en Java

0
Patricio

поле private доступно в классе/объекте, в котором оно объявлено. Он является приватным для других классов/объектов вне того, в котором он находится. 

0
ola