Java ООП Публичный против частного против защищенного - PullRequest
7 голосов
/ 11 декабря 2011

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

Мой вопрос: зачем мы это делаем?Почему у меня не должно быть одного класса, модифицирующего глобальные переменные другого класса напрямую?И даже если вам не нужно, зачем нужны защищенные, частные и публичные модификаторы?Как будто программисты не верят себе, что не делают этого, даже если они пишут программу.

Заранее спасибо.

Ответы [ 6 ]

9 голосов
/ 11 декабря 2011

Вы правы, это потому, что мы не можем доверять себе. Изменчивое состояние является основным фактором сложности компьютерных программ, слишком легко сначала создать что-то, что кажется нормальным, а затем выходит из-под контроля, когда система становится больше. Ограничение доступа помогает уменьшить вероятность непредвиденного изменения состояний объектов. Идея состоит в том, чтобы объекты общались друг с другом по четко определенным каналам, а не напрямую настраивали данные друг друга. Таким образом, у нас есть надежда на тестирование отдельных объектов и уверенность в том, как они будут вести себя как часть более крупной системы.

7 голосов
/ 11 декабря 2011

Позвольте мне привести простой пример (это только для иллюстрации):

class Foo {
  void processBar() {
    Bar bar = new Bar();
    bar.value = 10;
    bar.process();
  }
}

class Bar {
  public int value;
  public void process() {
    // Say some code 
    int compute = 10/value;
    // Her you have to write some code to handle
    // exception
  }
}

Все выглядит хорошо, и вы счастливы.Позже вы поняли, что другие разработчики или другие API-интерфейсы, которые вы используете для установки значения, устанавливают на 0, и это приводит к исключению в вашей функции Bar.process().

Теперь в соответствии с приведенной выше реализациейвы ни в коем случае не можете удержать пользователей от установки его в 0. Теперь посмотрите на реализацию ниже.

class Foo {
  void processBar() {
    Bar bar = new Bar();
    bar.setValue(0);
    bar.process();
  }
}

class Bar {
  public int value;
  public void setValue(int value) {
    if(value == 0)
      throw new IllegalArgumentException("value = 0 is not allowed");

    this.value = value; 
  }
  public void process() {
    // Say some code
    int compute = 10/value;
    // No need to write exception handling code
    // so in theory can give u better performance too

  }
}

Теперь вы можете не только поставить проверку, но и дать информативное исключение, которое может помочь быстро и быстро определить ошибкиstage.

Это только один из примеров, основ ООП (инкапсуляция, абстракция и т. д.), которые помогут вам стандартизировать интерфейс и скрыть нижележащую реализацию.

4 голосов
/ 11 декабря 2011

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

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

Еще один хороший момент - в документации / руководстве по Java: http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html:

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

2 голосов
/ 11 декабря 2011

Мой вопрос: зачем мы это делаем?

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

Большинство разработчиков понимают код с помощью умственного процесса абстракции;то есть мысленно рисует границы вокруг битов кода, понимая каждый бит изолированно, а затем понимая, как каждый бит взаимодействует с другими битами.Если какая-либо часть кода потенциально может связываться с «внутренностями» любой другой части кода, то типичному разработчику будет трудно понять, что происходит.

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

Почему у меня не должно быть одного класса, модифицирующего глобальные переменные другого класса напрямую?

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

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

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

Дело не в доверии.Речь идет о выражении в исходном коде, где границы.

Если я пишу класс и объявляю метод или поле private, я знаю, что мне не нужно рассматривать проблему того, что происходитесли другой класс вызывает его / обращается к нему / изменяет его.Если я читаю чужой код, я знаю, что могу (изначально) игнорировать части private при отображении взаимодействий и границ.Модификаторы private и protected и пакет private обеспечивают различную гранулярность границ.

(Или, может быть, речь идет о доверии; т.е. не доверяет нам до запомнить где границы абстракции в нашем дизайне есть / были.)

2 голосов
/ 11 декабря 2011
  • Нелокальное поведение сложно рассуждать.
  • Минимизация площади поверхности улучшает понимание.
  • Я не доверяю себе, чтобы запомнить все поведенческие побочные эффекты.
  • Я определенно не доверяю "вам", чтобы понять всеповеденческие побочные эффекты.
  • Чем меньше я выставляю, тем больше гибкости мне приходится модифицировать и расширять.
1 голос
/ 11 декабря 2011

Существует в основном две причины:

1) В Java есть интерфейсы, где требуется безопасность.Например, при запуске Java-апплета на вашем компьютере вы хотите убедиться, что апплет не может получить доступ к частям файловой системы, для которых он не авторизован.Без принудительной защиты апплет может проникнуть в уровень безопасности Java и изменить свои собственные права доступа.

2) Даже когда всем «доверяют», иногда целесообразность превосходит здравый смысл, и программисты обходят API-интерфейсы, чтобы получить доступ к внутренним интерфейсам.чем улучшение API (что по общему признанию может занять больше времени, чем практическое).Это создает проблемы как для стабильности, так и для совместимости при обновлении.

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

Обратите внимание, что эти проблемы существовали до парадигмы ООПстали обычным делом, и некоторые из мотивации для ООП.ООП - это не произвольная религиозная доктрина, придуманная из ничего, а набор принципов, отобранных за 6 лет опыта программирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...