Модификаторы доступа в объектно-ориентированном программировании

Я не понимаю модификаторы доступа в ООП. Почему мы делаем, например, переменные экземпляра Java частными, а затем используем общедоступные методы getter и setter для доступа к ним? Я имею в виду, какие рассуждения/логика стоят за этим?

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

пожалуйста, извините мое невежество, поскольку я просто пытаюсь понять, почему?

заранее спасибо. ;-)

9 ответов


это называется data или сокрытие информации.

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

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

например, предположим, что у меня есть Button управления и предоставил setText() вместо этого я мог бы просто добавить вызов перерисовки к этому методу setter.

в качестве другого примера предположим, что у меня есть класс, который открывает файл в своем конструкторе и назначает его public FileStream file. Конструктор создает исключение, если файл не удалось открыть. Поэтому другие методы в классе могут предположить, что это поле всегда допустимо. Однако, если кто-то будет совать нос в мой класс и устанавливает file to null, все методы в моем классе вдруг начинают рушится.


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

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


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

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


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


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


во-первых, не все члены данных должны иметь геттеры и сеттеры, и я полагаю, вы можете видеть достоинство сохранения этих переменных в секрете.

во-вторых, большинство классов больше, чем случайные наборы данных. Они представляют собой вещи, о которых вы должны быть в состоянии рассуждать независимо. Как правило, это означает, что они имеют определенные свойства, от которых разработчик может зависеть (часто называемые "инвариантами класса"). Например, класс Rectangle должен недвижимость, рисуя линии между угловыми точками дает линии под прямым углом друг к другу. Если точки являются членами общедоступных данных, любое случайное приложение может изменить точку, и тогда у вас будет прямоугольник, который не был прямоугольником. Если у вас есть функция setter, вы можете справиться с этим правильно.

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


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

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

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

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


Это основное преимущество использования ООП, полиморфизма, наследования и инкапсуляции.

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

с другой стороны, вы хотите мутировать данные, создавая метод setter. Надеюсь, это поможет.


вы говорите об основах ООП. На эту тему стоит почитать хорошую книгу. Различные блоги и форумы (один из которых является таковым) не являются подходящим местом для получения фундаментальных знаний.

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