Когда использовать методы получения / установки в java

Я хочу знать, когда использовать методы get и set (getName, setName) в моем классе, а когда просто classVariable.name = "" вместо а = classVariable.getName()

Вот пример класса, использующего методы set и get

public class ClassExampe {

    String name;
    String course;

    public String getName ( )
    {
        return name;
    }

    public void setName (String studentName)
    {
        name = studentName;           
    }

    public String getCourse ( )
    {
        return course;
    }

    public void setCourse (String studentCourse)
    {
        course = studentCourse;
    }
}

Спасибо


person Jovan    schedule 11.11.2010    source источник
comment
В случае сомнений используйте сеттеры / геттеры, однако, как только вы будете уверены, что эти методы вам никогда не понадобятся, например частные внутренние классы или локальные классы пакета или объект значения данных, вы можете попробовать отбросить их. Их можно будет довольно легко добавить позже, в зависимости от вашего проекта.   -  person Peter Lawrey    schedule 11.11.2010
comment
Лучше вообще избегать доступа к состоянию, если вы можете ... попросить клиента сделать что-то с объектом, а не запрашивать его состояние.   -  person Robert    schedule 11.11.2010
comment
Строго говоря, использование «get» / «set» в качестве части имени метода является отказом от спецификации JavaBean. На самом деле в этом нет необходимости, так как характер получения или установки метода можно увидеть в его сигнатуре метода. См. Примеры этого в Smalltalk.   -  person Joe    schedule 12.11.2010


Ответы (9)


Использование геттеров / сеттеров против использования полей

Как правило большого пальца:

используйте переменные непосредственно из того же класса (фактически из того же файла .java, поэтому внутренние классы тоже в порядке), используйте геттеры / сеттеры из других классов.

person Sean Patrick Floyd    schedule 11.11.2010

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

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

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

person Bozho    schedule 11.11.2010
comment
Могу ли я добавить, что использование закрытых членов и установщика / получателя также разрешает доступ только для чтения или только для записи. - person Lawrence Dol; 11.11.2010

В Java использование геттеров и сеттеров обычно считается лучшей практикой.

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

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

person Alan Geleynse    schedule 11.11.2010
comment
Добавьте к этому, что ваша собственность должна быть защищенной или частной. Это сокрытие информации, и вы не хотите, чтобы другие объекты могли изменять то, чего они не должны. - person Reverend Gonzo; 11.11.2010
comment
Я бы пошел так далеко, как никогда, кроме личного - person Robert; 11.11.2010

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

Одним из преимуществ является то, что у вас может быть больше, чем просто назначение и возврат. Пример:

public void setLevel(int lvl)
{
    if (lvl<0)
    {
        this.level=1;
    }
    else
        this.level = lvl;
}

public int getLevel()
{
    if (this.someIndicator==4)
        return this.level*7.1;
    else
        return level;
}
person FrustratedWithFormsDesigner    schedule 11.11.2010
comment
Почти -1 для использования однобуквенной переменной с именем 'l' (el), которая в большинстве шрифтов выглядит идентичной или почти идентичной цифре 1 (один). - person Lawrence Dol; 11.11.2010

Геттеры и сеттеры позволяют вам изменить реализацию позже (например, сделать что-то более сложное), позволяют реализовать правила проверки (например, setName выдает исключение, если имя не более 5 символов, независимо от того.)

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

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

В этом случае, если вы хотите получить доступ к атрибуту извне объекта и хотите, чтобы он был доступен для чтения / записи, я просто использую общедоступный атрибут. Это меньше кода, и это означает, что вы можете писать такие вещи, как obj.var += 5, которые легче читать, чем obj.setVar(obj.getVar() + 5).

person Adrian Smith    schedule 11.11.2010
comment
Я думаю, что лучший способ справиться с этим особым случаем - это использовать для этой цели метод: obj.incrVar(5); - person FrustratedWithFormsDesigner; 11.11.2010
comment
Да, в конце концов, все сводится к тому, как вы относитесь к этому предмету. Я знаю, что вы имеете в виду, и думаю, что в некоторых случаях это оправдано, но во многих действительно небольших объектах люди просто вкладывают слишком много времени и кода в геттеры / сеттеры; где небольшой объект с общедоступными атрибутами и клиент, делающий то, что необходимо, были бы правильным компромиссом между сложностью и безопасностью. Но, как я уже сказал, разные люди по-разному думают об этой теме .. - person Adrian Smith; 11.11.2010

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

Если вы имеете в виду, вызовите свои собственные методы get и set против прямого доступа к переменным w / в вашем классе, я все же говорю, что вызовите ваши собственные методы доступа. Таким образом, любые преобразования, изменения или правила, которые вы реализуете как часть get / set, будут автоматически вызываться вашими собственными внутренними вызовами, а также внешними вызывающими объектами.

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

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

person Joe    schedule 11.11.2010
comment
Я хотел бы отметить, что причины прерывания нисходящего потока за счет изменения общедоступных интерфейсов (которыми являются общедоступные переменные) не является побочным эффектом - это критическое изменение. Побочные эффекты возникают, например, когда вы вызываете метод-член, и он влияет на состояние вне экземпляра объекта, для которого он был вызван, например, установка статического значения в любом классе. Или на языках, отличных от объектно-ориентированных, когда он влияет на что-либо, кроме переданных ему аргументов. В библиотеке C есть много функций, которые вызывают побочные эффекты - я использую слово функция в том смысле, в котором оно используется в C, а не в функциональном программировании. - person Lawrence Dol; 11.11.2010
comment
потрясающая гнида (или пивной чат), но я не уверен, что согласен с тем, что публичные вары являются частью «интерфейса». Я склонен думать об интерфейсе как о явном поведении, а не о представлении данных. - person Joe; 12.11.2010

Это дело вкуса, но, вообще говоря, вы всегда должны использовать методы get / set для всех общедоступных свойств. Но для таких вещей, как Value Objects (VOs), о которых вы, вероятно, не будете беспокоиться в течение некоторого времени, вы можете использовать общедоступные переменные, не получая слишком много критики, я думаю.

person Piotr    schedule 11.11.2010
comment
Я бы критиковал публичные вары ... - person bwawok; 11.11.2010
comment
Хе-хе, конечно, кто-нибудь :) - person Piotr; 11.11.2010

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

Круглая скобка: Однако это вполне возможно в других языках, например в Scala, когда граница между свойствами и методами может стать довольно тонкой. И это здорово, поскольку тогда это не становится проблемой кодирования, которая мешает, и делает использование более прозрачным.


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

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


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

person haylem    schedule 11.11.2010
comment
(Большинство людей просто заключают мысли в круглые скобки вместо того, чтобы комментировать абзац словом.) - person Lawrence Dol; 11.11.2010
comment
Думаю, я многословный парень, возможно, поэтому я не против явных геттеров и сеттеров. (Но это было действительно смешно. Видите, я использую его почти прямо здесь). - person haylem; 11.11.2010

Инкапсулируйте частные поля класса и выставляйте их с помощью классов получателей / установщиков так, как вы хотите.

person dimitrisli    schedule 11.11.2010