Как вы принимаете решение определить переменную "private"? - PullRequest
14 голосов
/ 24 ноября 2010

Я посещал собеседование. Интервьюер спросил меня, зачем вам личная переменная. Если вы достигаете чего-то, определяя переменную private, не можете ли вы достичь того же, определяя любой другой модификатор доступа, определенный в Java?

According to Java Specification Languages,

A private class member or constructor is accessible only within the body of the
top level class (7.6) that encloses the declaration of the member or constructor.
It is not inherited by subclasses.

Но, если я разрабатываю класс, как я могу принять решение определить переменную "private"?

Ответы [ 9 ]

40 голосов
/ 24 ноября 2010

Ограничивая доступ к «другому коду» (возможно, написанному / поддерживаемому другими), вы можете более свободно изменять его в будущем, не беспокоясь о том, чтобы взломать какой-то другой код, который зависит от него.Вопрос не в том, «должен ли я сделать это частным?», А в том, «нужно ли, чтобы это было не частным?».Есть ли какой-то другой код, который может нуждаться в доступе к переменной?

Если это так, вы назначаете надлежащий доступ (возможно, через геттеры / сеттеры) и принимаете, что изменить его будет сложно.Иначе вы оставите это в тайне.

11 голосов
/ 24 ноября 2010

Я думаю, вам стоит взглянуть на это с другой стороны: зачем вам делать переменную, кроме приватной? Под правильной инкапсуляцией подразумевается скрытие деталей вашей реализации, поэтому по умолчанию следует сделать поля приватными.

8 голосов
/ 24 ноября 2010

Как правило, после того, как вы сделаете переменную public, вы будете привержены и никогда не сможете вернуться к этому решению. Каждое будущее изменение изменит открытый интерфейс вашего класса, что, в свою очередь, означает, что необходимо изменить каждое использование этого класса. Для публичного API это немыслимо; ваша библиотека фактически сломала обратную совместимость.

Даже для частных классов это довольно большое дело.

Так когда же вы когда-нибудь измените область действия переменной на private в будущем? Есть много возможных причин для этого. Самым простым является то, что вашему классу может потребоваться что-то делать каждый раз, когда изменяется значение переменной (например, регистрировать изменение или обновлять другие переменные соответственно). Или позже вы решите, что переменная вообще не нужна, и что запрашиваемое пользователем значение должно вычисляться на лету.

Если вы непосредственно читаете или устанавливаете переменную, это невозможно. Вместо этого вашему классу нужно заставить пользователя вызывать метод получения / установки, запретив прямой доступ к переменной и предлагая вместо него соответствующие общедоступные методы получения / установки.

Поскольку в общем случае вы не можете никогда предвидеть такие будущие изменения, стало общепринятой практикой делать нет переменной public. Каждая переменная должна быть private (или, по крайней мере, внутренней).

(Есть одно исключение: в некоторых случаях final переменные можно безопасно сделать public. Например, константы, подобные enum, часто реализуются как переменные public final в библиотеках Java, потому что они никогда не изменятся, и нет требуется контроль доступа, так как в любом случае они доступны только для чтения).

7 голосов
/ 24 ноября 2010

Общее правило заключается в сокращении области применения переменных и методов.Чем больше вещей вы держите в секрете, тем легче вы можете изменить свой класс, не вызывая проблем в других частях системы (например: вы уменьшаете связь).

3 голосов
/ 24 ноября 2010

Если вы достигаете чего-то, определяя переменную private, разве вы не можете достичь того же, определяя любой другой модификатор доступа, определенный в Java?

Да. Это правда. Любой private можно изменить на public (или protected и т. Д.), И программа будет скомпилирована и запущена так же, как и раньше.

Модификаторы доступа предназначены для удобства программиста и помогают ему правильно определить интерфейс класса. Взгляните на статью в Википедии об инкапсуляции .

3 голосов
/ 24 ноября 2010

Итак, вы должны спросить себя, почему это должно быть частным.Итак, как насчет использования истины с помощью идеи противоречия?

Может ли она быть общедоступной? Если ответ таков, вы не хотите, чтобы люди могли иметь доступ и изменять атрибут напрямую, тогдаон не может быть общедоступным.

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

Может ли он быть защищен Если ответ таков, вы не хотите, чтобы подклассы обращались к атрибуту и ​​изменяли его напрямую, тогда он не может быть защищен.

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

Вопрос задает вопрос: действительно ли вы понимаете, что такое модификаторы?дать вам, и как они могут быть доступны, а не слепо делать все частным и создавать сеттеры и геттеры, потому что это то, чему вас научил ваш лектор / книга / пособие.

2 голосов
/ 24 ноября 2010

член является закрытым в случаях:

  1. это свойство, его чтение и запись должны выполняться только с помощью методов класса
  2. это имеет смысл только в контекстеобъект и нигде больше
  3. он не должен быть виден снаружи класса

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

1 голос
/ 24 ноября 2010

Основная задача классов - инкапсулировать данные и поведение и скрыть внутреннюю реализацию, одновременно предоставляя чистый, простой и полезный API.

Необходимо учитывать две разные вещи: публичный контракт (API) и личные данные.

  1. Личные поля: это ваши личные данные, которые вы не хотите раскрывать извне из-за: безопасности и целостности.

  2. Частные методы: ваши служебные функции делают код более читабельным и понятным.

  3. Открытые методы: контракт (интерфейс, API), который вы предоставляете другим людям. Вот что делает ваши занятия полезными.

  4. Открытые поля: не используйте это. Он раскрывает только часть ваших внутренних данных. Для простых классов может быть хорошо, в то время как для сложных классов со взаимозависимыми полями это большое нет-нет. Для демонстрации функциональности вы должны использовать публичные методы (пункт 3).

0 голосов
/ 24 ноября 2010

Многие из этих комментариев относятся к внутреннему / вложенному классу, методам и конструкторам.

По сути, вы хотите сделать доступ максимально ограниченным, не создавая излишнюю сложность. Если вы можете сделать что-то личное или статичное, я предлагаю вам это. Если вы можете сделать финал поля, это обычно также помогает улучшить ясность.

Когда поле или любой элемент является закрытым, вы можете сразу увидеть, где оно используется и когда оно больше не используется.

...