Каково использование инкапсуляции, когда я могу изменить значения свойств с помощью методов setter?

Я пытаюсь понять много раз, но я не понял этого.

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

Как мы можем изменить значения полей с помощью методов setter? Как предотвратить прямой доступ к полям? Каково реальное использование инкапсуляции?

Ответ 1

Предположим, что у вас есть свойство age.

Пользователь может ввести значение -10, которое, хотя и является допустимым числом, является недопустимым. Метод setter может иметь логику, которая позволит вам поймать такие вещи.

Другим сценарием было бы иметь поле 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.
}

Ответ 2

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

Ответ 3

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

Люди всегда говорят, что инкапсуляция - это "скрытие информации", поэтому, возможно, сделать инкапсуляцию фокусом на безопасность в качестве основного использования. Да, вы скрываете информацию на практике, но это не должно быть определением, поскольку это может смутить людей.

Инкапсуляция - это просто "минимизация взаимозависимостей между отдельно написанными модулями путем определения строгих внешних интерфейсов" (цитата из книги). То есть, когда я строю модуль, я хочу, чтобы между моими клиентами и мной был строгий контракт о том, как они могут получить доступ к моему модулю. Причина в том, что я могу улучшить внутреннюю работу, не делая этого АФФЕКТИВЫ моего клиента, жизни, приложения или того, для чего они используют мой модуль. Поскольку их "модуль" точно не зависит от внутренних операций моего модуля, но зависит от "внешнего интерфейса", я сделал доступным для них.

Итак, если я не предоставляю своему клиенту сеттер и дал им прямой доступ к переменной, и я понимаю, что мне нужно установить какое-то ограничение на переменную до того, как мой клиент сможет ее использовать, я меняю ее, меня, меняя жизнь моего клиента или приложение моего клиента с ОГРОМНЫМ РАСХОДОМ. Но если я предоставил "строгий контракт", создав "строгий внешний интерфейс", то есть, я могу легко изменить свою внутреннюю работу с очень небольшим или никаким расходом для моих клиентов.

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

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

Надеюсь, это объяснит это правильно. Если нет, вы можете перейти по ссылкам ниже и прочитать для себя.

вопросы инкапсуляции

Инкапсуляция и наследование в объектно-ориентированных языках программирования

Ответ 4

Любые способы изменения значений полей с помощью методов установки.

Только если метод setter позволяет это сделать.

Как мы предотвращаем доступ к полям?

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

Установщик может проверить, действительно ли значение. Он может спросить SecurityManager, если вам разрешено это делать. Он может конвертировать между типами данных. И так далее.

Ответ 5

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

Вы можете запретить запись или чтение доступа к полю (например, только предоставляя getter или setter соответственно), но инкапсуляция со свойствами позволяет вам делать больше, чем просто.

Ответ 6

Если у вас есть частные поля, к ним нельзя получить доступ за пределами класса, это означает, что в основном эти поля не существуют для внешнего мира, и да, вы можете изменить их значение с помощью методов setter, но используя методы setter, у вас больше гибкости/контроль, чтобы сказать, кто получает, чтобы изменить поля и какое значение они могут быть изменены... в основном с инкапсуляцией вы можете установить ограничения на то, как и кто изменяет ваши поля. Например, у вас есть: частная двойная зарплата, метод 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");    
} 

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

Ответ 7

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

  • Инкапсулированный код более гибкий и легко меняющийся с новыми требованиями
  • Позволяет вам контролировать , кто может получить доступ к. (!!!)
  • Помогает писать immutable class в Java
  • Это позволяет вам изменить одну часть кода, не затрагивая другую часть кода.

Ответ 8

Доступ к полям через методы делает разницу, потому что он делает ООП. Например, вы можете расширить свой класс и изменить поведение, которое вы не можете сделать с прямым доступом. Если у вас есть геттеры/сеттеры, вы можете сделать прокси-сервер своего класса и сделать AOP или сделать динамический прокси 1.4. Вы можете сделать издевательства над своим классом и сделать модульное тестирование...

Ответ 9

Предположим, вы создали пользовательский класс Date со следующими сеттерами/получателями:

getDay() 
getMonth() 
getYear() 
setDay() 
setMonth() 
setYear()

Внутренне вы можете сохранить дату, используя:

private int day;
private int month;
private int year;

Или вы можете сохранить дату с помощью java.lang.Date-объекта:

private Date date;

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

Ответ 10

Encapsultaion используется для скрытия переменных-членов, делая член как закрытый и доступ к этой переменной-члену методом getter и setter.

Пример

класс Инкапсуляция {

private int value ;

Encapsulation() {
    System.out.println("constructor calling ");
}

void setValue(int value){
    this.value = value;
}
int getValue() {
    return value;
}

} class 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());
}

}

вы не можете получить доступ к закрытому значению вне класса.

Ответ 11

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

Ответ 12

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

Вы меняете значения, предоставляя публичный доступ к этим методам (сеттерам).

с помощью инкапсуляции поля класса могут быть сделаны read-only или write-only.

Ответ 13

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

public Object object;

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

public Object getObject() { 

return object;
}

public void setObject(Object object) { 

this.object = object;
}

Ответ 14

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

-Вы можете выполнить некоторые записи в ваших методах getter/setter.

-Вы можете проверить/нормализовать (например, триммеры, удалить специальный символ,...) Ваш ввод в методе setter.

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

public List<t> get collection(){
 return new  ArrayList<t>(this.arrayList);
}

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

Ответ 15

Основная идея инкапсуляции - скрытие данных. Существует несколько причин, по которым мы используем инкапсуляцию в объектно-ориентированном программировании. Некоторые из выявленных причин, почему мы инкапсулируем следующие (Реальное использование инкапсуляции).

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

  • Сделать отладку проще. Это соответствует приведенной выше точке. Мы знаем, что объект можно манипулировать только с помощью методов. Таким образом, это упрощает отладку и обнаружение ошибок.

  • Имейте контролируемую среду. Позвольте пользователям использовать данные объекты контролируемым образом через объекты.

  • Скрыть сложности. Скрывать сложности, не относящиеся к пользователям. Иногда некоторые свойства и методы используются только для внутреннего использования, и пользователь не должен знать об этом. Это упрощает пользователю использование объекта.

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

  • Вы можете ограничить значения, которые могут быть сохранены в поле (т.е. пол должен быть F или M).

  • Вы можете выполнять действия, когда поле изменяется (событие триггера, проверка и т.д.).

  • Вы можете обеспечить безопасность потоков, синхронизируя метод.

  • Вы можете переключиться на новое представление данных (т.е. вычисленные поля, разные типы данных)