2

Я не могу понять зачем в java нужны get и set когда есть public.

Понятное дело что это модификаторы доступа, что если private то доступ к ним получить можно через get и set. Но зачем это все.

Если есть public?

почему нельзя просто использовать public int test; obj.test

Вопрос в том что будет если я буду использовать public, вместо геттеров и сеттеров. Реальная причина почему так нельзя делать. Я это хочу узнать.

А не то что создатели java просто решили что нужно ограничить переменные и придумали private, я хочу узнать что послужило создателям java добавить private.

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


@Виктор, Ваш ответ более менее несет ту информацию которую я ищу, но вот вопрос. Допустим переменная index имеет тип int. Но в этом классе есть метод get который возвращяет String.

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

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


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

Вот напрямую public player.car.speed++;

А это get и set getPlayer().getCar().setSpeed(getPlayer().getCar().getSpeed()+1);

Такое ощущение что будто смотришь на Торт и пирожное =)

  • 3
    вам стоит почитать про ООП (Объектно-ориентированное программирование), ответ на ваш вопрос вы найдете при рассмотрении инкапсуляции... – mit Nov 16 '17 at 16:27
  • Вы меня не поняли. Я знаю ООП, И читал не раз. Но вопрос мой вы не поняли. Прочитайте еще раз –  Nov 16 '17 at 16:34
  • 3
    Есть специальные заглушки для розеток. – Roman C Nov 16 '17 at 16:35
  • Проблема в том, что программисты ОЧЕНЬ любят совать пальцы в розетки ;) – andreymal Nov 16 '17 at 16:38
  • @EraNewGames знать - не значит понимать. Ваш пример с розетками - если ваша розетка открыта, то я придя к вам в гости смогу отвернуть болтик и отключить провода, т.е. модифицировать ваш код так, как вы не задумывали. После такой модификации ваша розетка перестанет работать. Или вы живете затворником и кодите в одиночестве для себя? Если так - забудьте все о че мы говорили ) – mit Nov 16 '17 at 16:38
  • Самый лучший и понятный ответ на этот вопрос приходит при попытке поддерживать и развивать в течении десяти лет код из миллион строк для приложения минута простоят которого стоит от половины твоей зарплаты и выше. – Sergey Gornostaev Nov 16 '17 at 16:40
  • 2
    На самом деле вопрос очень простой, так как public и геттеры\сеттеры позволяют получать\модифицировать переменную\значение. В чем разница? В том что в первом случае вы не можете отслеживать изменение значения переменной, так как это может происходить за пределами вашего кода. Во втором случае вы можете контролировать эти изменения, которые приходят извне.Вот собственно и все. Для более подробных вещей советую почитать о JavaBeans и про менеджер безопасности. – Roman C Nov 16 '17 at 16:59
  • «А не то что создатели java просто решили что нужно ограничить переменные и придумали private» — а вы private-методами тоже не пользуетесь? По вашей логике, просто нужно написать комментарий, чтобы методом не пользовались, и всё. – VladD Nov 16 '17 at 17:24
  • Ещё по смежной тематике: https://ru.stackoverflow.com/q/197067/10105 – VladD Nov 16 '17 at 17:32

1 Answers1

7

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

вот тут вы не правы, дети не знают и есть розетки с защитой от детей.

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


Геттеры и сеттеры скрывают в чем храниться информация. Так же в сеттере можно проводить валидацию новых данных.

Допустим у вас класс хранит ip адрес, как вы его будете хранить?

  • в строке
  • в числе
  • в массиве чисел

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

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

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

С сеттером то же самое, вы можете хранить в любом формате и принимать в любом. В самом сеттере вы можете делать любые нужные вашему коду преобразования, пользователь об этом не узнает.


В общем методы set и get это часть внешнего API, который желательно менять как можно реже, иначе может всплыть много проблем.

Виктор
  • 4,922
  • в гетеры\сеттеры не нужно ничего писать, они должны автоматически генериться, или же просто использовать ломбок, хотя я не люблю это. – Roman C Nov 16 '17 at 17:05
  • 1
    @RomanC геттеры и сеттеры как часть API могу содержать логику для поддержания валидности объекта. – Виктор Nov 16 '17 at 17:09
  • могут это не значит что должны, делать валидацию полей нужно извне а не внутри объекта. JSR303\349. – Roman C Nov 16 '17 at 17:13
  • @RomanC где я написал, что они что-то должны? я написал про возможности геттеров и сеттеров и примерную цель их использования. Каждый дальше сам решит как и что писать – Виктор Nov 16 '17 at 17:16
  • я еще раз повторяю вам - можно это не значит что нужно\должны, вы везде пишете что можно делать то, можно другое, но это абсолютно не нужно, и такой код в большинстве случаев приходится рефакторить путем выноса логики в сервисы. – Roman C Nov 16 '17 at 17:29
  • @RomanC: Не вопрос, а кто триггернёт эту логику в сервисе, если не сеттер? – VladD Nov 16 '17 at 17:32
  • @VladD тот кто использует этот сервис, ну а сеттер триггернет тот кто использует бин (тот же самый сервис). – Roman C Nov 16 '17 at 17:35
  • @Виктор: Ну это тоже не лучшее решение — получается, что тот, кто пользуется объектом, должен знать ещё и сервис, который нужно дёргать каждый раз после обновления свойств объекта. – VladD Nov 16 '17 at 17:37
  • @Виктор, я обновил вопрос посмотрите –  Nov 16 '17 at 19:28
  • @EraNewGames чтобы не было таких цепочек, стоит использовать "Информационных эксперт". Т.е. в вашем случае в классе Player создать метод getCarSpeed и setCarSpeed. Пусть плеер делегирует эту обязанность машине, т.к. скорость машины - информация принадлежащая машине. Опять же ве это зависит от архитектуры и ваших нужд. – Виктор Nov 16 '17 at 19:41