Java

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

Кирилл $
Кирилл $
1 186
Если что-то ещё нужно сделать. Например, проверить допустимость присваиваемых значений. Или вызвать функцию, чтобы переместить элемент UI на экране при задании новых координат, например.
Олег Натей Голенко
Олег Натей Голенко
12 356
Лучший ответ
Кирилл $ Написать функцию или испоьзовать готовую.
а зачем ты деньги прячешь? выложил бы где-нибудь на видном месте. было бы тебе удобно. и всем тоже.
Вчера ты хранил данные в переменной, а сегодня сделал её вычисляемой на ходу - внешне при использовании сеттеров и геттеров ничего не изменилось
Dima @mai.ru
Dima @mai.ru
96 953
Кирилл $ Так ли это важно?
Я счаз "Теорию большого взрыва " пересмотрю и вернусь, наверное...
Arman Абдреев
Arman Абдреев
69 504
поля чтобы public не делать, да и вообще хороший тон в ооп
Кирилл $ Смысл "public не делать" только в том, чтобы скрыть поле. Но если это поле будет доступно через метод, то зачем это всё?
Это инкапсуляция. Мы скрываем реализацию. В геттере сеттере тебе достаточно знать, что ты должен отправить и что ты должен получить. Какая магия внутри тебя не интересует от слова совсем.
Это контракт твоего класса с другими классами.

Пример - ты хранишь сумму платежа в int. Тут где-то случился дефолт и у них пошли суммы в миллиарды. Тебе надо резко менять тип.
При использовании сеттеров ты просто создаешь еще один set с float на вход, а в старом сетере делаешь конвертацию типов.
Все счастливы - те кому не нужны большие суммы пользуются старым сеттером не зная, что у тебя что-то поменялосью. кому надо большие суммы гонять - используют новый сеттер, а у тебя все данные хранятся в одном месте в удобном для тебя формате.
Ozgur Simsek
Ozgur Simsek
18 396
Пусть есть поле "угол", private int angle.

1. Сперва делаешь простенький сеттер:

public void setAngle(int angle) {
this.angle = angle;
}

2. А спустя какое-то время замечаешь, что туда передают всякую непотребщину, хотя допустимое значение угла - [0; 360]. Если ты открыл само поле, у тебя проблемы уже на этом этапе.

public void setAngle(int angle) {
this.angle = angle % 360;
}

3. Потом тебе потребовалось добавить логирование на это действие:

public void setAngle(int angle) {
log("Angle set");
this.angle = angle % 360;
}

4. В каком-то классе появилась необходимость "подписаться" на изменения значения поля (например, чтобы отображать где-то обновленное значение):

public void setAngle(int angle) {
log("Angle set");
this.angle = angle % 360;

listener.onAngleChanged();
}

5. В конце концов ты в корне изменил реализацию класса и поле angle оказывается ненужным. Поле удаляешь, а аксессоры помечаешь устаревшими, но на какое-то время оставляешь, чтобы у тех, кто пользуется твоим классом, ничего не сломалось:

@Deprecated
public void getAngle() { return 0; }

@Deprecated
public void setAngle(int angle) { /** do nothing */ }

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

Кроме того, регулярно встречаются ситуации, когда поле нужно открыть только на чтение, но не запись (т. е. изменяться такое поле должно только в пределах твоего класса). Например, если ты реализуешь какой-то утилитарный класс для чтения из файла, таким полем может быть количество прочитанных на данный момент байт. Бессмысленно делать его доступным для записи кому-то со стороны. В таком случае заводится приватное поле и геттер, без сеттера.
Gerasimov Aleksandr Супер, спасибо!
Не нарушаем главной концепции ООП
Два раза вызвать поля для разных значений не сможешь без методов геттеров и сеттеров, не усложняй себе жизнь, говнокод на говнокоде
Veter Gal
Veter Gal
123
Кирилл $ "вызвать поля"?
Veter Gal Ой, поле