Какой смысл в инкапсуляции, когда я могу изменить значения свойств с помощью методов setter?
Я пытаюсь понять много раз, но я не понимаю этого.
инкапсуляция-это метод создания полей в классе private и обеспечение доступа к полям публичными методами. Если поле объявлены как private, он не может быть доступна никому за пределами класса, тем самым скрывая поля внутри класса.
Как мы можем изменить значения полей с помощью методов сеттер? Как предотвратить доступ к полям напрямую? Какова реальная польза инкапсуляции?
15 ответов
Предположим, у вас есть age
собственность.
пользователь может ввести значение -10
, который, хотя и является допустимым числом, является недопустимым возрастом. Сеттера может иметь логику, которая позволит вам ловить такие вещи.
другой сценарий, было бы иметь age
поле, но скрывают это. У вас также может быть поле даты рождения, и в его сеттере у вас будет что-то вроде:
...
private int age
private Date dob
...
public void setDateOfBirth(Date dob)
{
this.dob = dob;
age = ... //some logic to calculate the age from the Date of Birth.
}
Я также был смущен, как и вы, в течение долгого времени, пока я не прочитал книгу инкапсуляции и наследования на объектно-ориентированном языке программирования и веб-сайте, который объяснил важность инкапсуляции. Меня направили с сайта на книгу.
люди всегда говорят, что инкапсуляция-это "скрытие информации", поэтому, возможно, инкапсуляция фокусируется на безопасности в качестве основного использования. Да вы скрываете информацию на практике, но это не должно быть определение, как это может запутать людей.
инкапсуляция-это просто "минимизация взаимных зависимостей между отдельно написанными модулями путем определения строгих внешних интерфейсов" (цитата из книги). То есть, когда я строю модуль, мне нужен строгий контракт между моими клиентами и мной о том, как они могут получить доступ к моему модулю. Причина в том, что я могу улучшить внутреннюю работу, не влияя на жизнь моего клиента, приложение или то, для чего они используют мой модуль. Поскольку их " модуль "точно не зависит от внутренней работы моего модуля, а зависит от" внешнего интерфейса", я сделал его доступным для них.
поэтому, если я не предоставлю своему клиенту сеттер и не дам им прямой доступ к переменной, и я понимаю, что мне нужно установить некоторое ограничение на переменную, прежде чем мой клиент сможет ее использовать, я изменяю ее, могу быть мной, изменяя жизнь моего клиента или применение моего клиента с огромными расходами. Но если бы я предоставил " строгий контракт "путем создания" строгого внешнего интерфейса " i.e сеттер, тогда я могу легко изменить свою внутреннюю работу с очень небольшими затратами или без них для моих клиентов.
в ситуации сеттера (с использованием инкапсуляции), если это произойдет, когда вы установите переменную, и я верну сообщение, сообщающее вам, что она была назначена, теперь я могу отправить сообщение через мой "интерфейс", информируя моего клиента о новом способе взаимодействия с моим модулем, я.e "вы не можете назначить отрицательные числа", то есть если мои клиенты пытаются присвоить отрицательный номер. Но если я не использовал инкапсуляцию и дал моему клиенту прямой доступ к переменной, и я делаю свои изменения, это может привести к сбою системы,потому что, если ограничение, которое я реализовал, заключается в том, что вы не могли сохранять негативы, и мой клиент всегда мог хранить негативы, у моих клиентов будет разбитая система в их руках (если эта "разбитая система" была банковской системой, представьте, что может произойти).
Так инкапсуляция больше о уменьшение зависимости между модулем, поэтому улучшение можно сделать "тихо" с небольшим или никаким расходом на другие модули, взаимодействующие с ним, чем безопасность. Потому что взаимодействующие модули зависят от"строгого внешнего интерфейса или строгого контракта".
Я надеюсь, что это объясняет его правильно. Если нет, вы можете перейти по ссылкам ниже и прочитать для себя.
инкапсуляция и наследование в объектно-ориентированном Языки Программирования
реальное использование инкапсуляции также заключается в том, что вы можете выполнять дополнительные проверки/обработку по способу установки значений.
вы точно не препятствуете доступу к полям - вы контролируете, как другие могут получить доступ к определенным полям. Например, можно добавить проверку в метод setter или обновить другое зависимое поле при вызове метода setter поля.
вы можете запретить доступ к полю для записи или чтения (например, предоставив только геттер или сеттер соответственно), но инкапсуляция со свойствами позволяет вам делать больше, чем просто это.
любой, как я могу изменить значения полей с помощью методов setter.
только если метод setter позволяет это сделать.
Как мы предотвращаем доступ к полям?
сеттер и геттер вам контролировать, если и как вы можете получить доступ к полям.
сеттер может проверить, является ли значение допустимым. Он может запросить SecurityManager, если вам разрешено это делать. Он может конвертировать между типами данных. И так далее.
Если у вас есть частные поля, они не могут быть доступны вне класса, это означает, что в основном эти поля не существуют во внешнем мире, и да, вы можете изменить их значение с помощью методов сеттера, но с помощью методов сеттера у вас есть больше гибкости/контроля, чтобы сказать, кто получает изменить поля и на какое значение они могут быть изменены...в основном с инкапсуляцией вы можете установить ограничения на то, как и кто изменяет ваши поля. Например, у вас есть: частная двойная зарплата, метод setter может ограничить, что только персонал hr может изменить поле зарплаты, оно может быть написано как:
void setSalary(Person p,double newSalary)
{
//only HR objects have access to change salary field.
If(p instanceof HR && newSalary>=0)
//change salary.
else
S.o.p("access denied");
}
представьте, если бы зарплата была публичной и могла быть доступна напрямую, любой может изменить ее, однако и всякий раз, когда они хотят, это в основном значение инкапсуляции
это цель-не что иное, как защита всего, что склонно к изменениям. У вас есть много примеров в интернете, поэтому я даю вам некоторые из его преимуществ:
- инкапсулированный код гибкий и легко изменить в соответствии с новыми требованиями
- позволяет контролировать кто может получить доступ к. (!!!)
- помогает писать
immutable class
в Java - Это позволяет изменять часть of код, не затрагивая другую часть кода.
доступ к полям через методы имеет значение, потому что это делает его ООП. Например, вы можете расширить свой класс и изменить поведение, которое вы не можете сделать с прямым доступом. Если у вас есть геттеры / сеттеры, вы можете сделать прокси своего класса и сделать AOP или A сделать 1.4 динамический прокси. Вы можете сделать макет из своего класса и сделать модульное тестирование...
предположим, вы создаете пользовательский класс даты со следующими сеттерами / геттерами:
getDay()
getMonth()
getYear()
setDay()
setMonth()
setYear()
внутренне вы можете сохранить дату, используя:
private int day;
private int month;
private int year;
или вы можете сохранить дату с помощью java.ленг.Дата-объект:
private Date date;
инкапсуляция не раскрывает, как ваш класс работает внутри. Это дает вам больше свободы, чтобы изменить, как работает ваш класс. Это дает вам возможность контролировать доступ к вашему классу. Вы можете проверить, входит ли пользователь действительно (Вы не хотите, чтобы пользователь вводил день со значением 32).
Encapsultaion используется для скрытия переменных-членов ,делая член как закрытый и доступ к этой переменной-члену методами getter и setter.
пример
инкапсуляция класса{
private int value ;
Encapsulation() {
System.out.println("constructor calling ");
}
void setValue(int value){
this.value = value;
}
int getValue() {
return value;
}
} класс EncapsulationMain {
public static void main(String args[]) {
Encapsulation obj = new Encapsulation();
obj.setValue(4);
//System.out.print("value is "+obj.value);
//obj.value = 55;
//System.out.print("obj changing the value"+obj.value);
System.out.print("calling the value through the getterMethod"+obj.getValue());
}
}
вы не можете получить доступ к закрытому значению вне класса.
Ну, инкапсуляция-это не только сокрытие данных. Это все о получении контроля над тем, что хранится в полях. Используя инкапсуляцию, мы можем сделать поле доступным только для чтения или записи в зависимости от требований.Также пользователи не знают, как данные хранятся в полях. Мы можем использовать специальное шифрование в методах setter и хранить его в полях. Например, человек-это объект. Мы требуем только, чтобы поле имени человека читалось пользователем, но не было модифицированный. Затем мы определяем только метод get в поле name.Вот как инкапсуляция полезна.
основная идея инкапсуляции-это скрытие данных. Существует несколько причин, по которым мы используем инкапсуляцию в объектно-ориентированном программировании. Некоторые из выявленных причин, почему мы инкапсулируем, следующие (реальное использование инкапсуляции).
лучше ремонтопригодность: когда все свойства являются частными и инкапсулированными, нам легко поддерживать программу, просто изменяя методы.
Отладка Простой: Это соответствует приведенной выше точке. Мы знаем, что объектом можно манипулировать только методами. Таким образом, это позволяет легко отлаживать и ловить ошибки.
иметь контролируемую среду: пусть пользователи используют данные объекты контролируемым образом через объекты.
Скрыть Сложности: скрытие сложностей, не относящихся к пользователям. Иногда некоторые свойства и методы предназначены только для внутреннего использования, и пользователю не обязательно знать об этом. Это делает простым для пользователя использование объекта.
Итак, чтобы ответить на вопрос, "в чем польза инкапсуляции, когда я могу изменить значения свойств с помощью методов setter?", приведенные выше некоторые из основных причин, почему мы используем инкапсуляцию. Чтобы обеспечить понимание на почему, геттеры и сеттеры являются полезным, ниже приведены некоторые важные моменты, полученные из этого статьи.
вы можете ограничить значения, которые могут быть сохранены в поле (т. е. пол должен быть F или M).
вы можете выполнять действия при изменении поля (событие триггера, проверка и т. д.).
вы можете обеспечить безопасность потока путем синхронизации метода.
вы можете переключиться на новое представление данных (т. е. вычисляемые поля, разные типы данных)
Если у вас есть класс, все его свойства являются частными-это означает, что к ним нельзя получить доступ извне класса - и единственный способ взаимодействия со свойствами класса-через его общедоступные методы.
вы изменяете значения tha, предоставляя открытый доступ к этим методам (сеттерам).
используя инкапсуляцию, можно сделать поля класса read-only
или write-only.
вместо того, чтобы позволить каждому получить доступ к переменным напрямую:
public Object object;
лучше использовать методы SET и GET или, например, только метод GET (иногда вы не хотите, чтобы кто-то устанавливал другое значение этой переменной).
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
используя инкапсуляцию, вы отделяете свой класс от внешнего мира (других классов), а внешний мир может получить доступ и изменить переменные экземпляра класса с помощью модификаторов доступа, что обеспечивает несколько преимуществ:
- вы можете выполнить вход в свои методы getter/setter.
- вы можете проверить / нормализовать (например, обрезать пробелы, удалить специальный символ,...) Ваш ввод в метод setter.
а также вы можете скрыть свою реализацию от внешний мир, например, у вас есть коллекция, как список массивов в вашем классе, и вы пишете свой метод getter, как это
public List<t> get collection(){
return new ArrayList<t>(this.arrayList);
}
таким образом, в этом случае в будущем, если вы решите изменить свою реализацию коллекции из списка массивов на что-то еще, например связанный список, вы можете сделать это, потому что внешний мир ничего не знает о вашей реализации.