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

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

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

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

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

7
задан Dave Jarvis 11 March 2010 в 20:25
поделиться

9 ответов

Это называется сокрытием данных или информации .

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

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

Например, предположим, что у меня есть элемент управления Button с открытым полем текстовой строки . Теперь все начинают использовать мою кнопку , но я понимаю, что кнопку действительно нужно перерисовывать на экране при изменении текста. Мне не повезло, потому что мой объект не может определить, когда назначен текст .Если бы я сделал его закрытым и вместо него предоставил setText () , я мог бы просто добавить вызов перерисовки к этому методу установки.

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

11
ответ дан 6 December 2019 в 08:42
поделиться

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

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

6
ответ дан 6 December 2019 в 08:42
поделиться

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

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

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

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

0
ответ дан 6 December 2019 в 08:42
поделиться

Вы говорите об основах ООП. Эта тема заслуживает прочтения хорошей книги. Различные блоги и форумы (один из которых - SO) - не лучшее место для получения фундаментальных знаний.

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

0
ответ дан 6 December 2019 в 08:42
поделиться

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

1
ответ дан 6 December 2019 в 08:42
поделиться

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

1
ответ дан 6 December 2019 в 08:42
поделиться

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

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

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

0
ответ дан 6 December 2019 в 08:42
поделиться

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

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

1
ответ дан 6 December 2019 в 08:42
поделиться

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

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

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

1
ответ дан 6 December 2019 в 08:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: