Поиск…


Вступление

В этой статье обсуждаются геттеры и сеттеры; стандартный способ обеспечения доступа к данным в Java-классах.

Добавление геттеров и сеттеров

Инкапсуляция является базовой концепцией в ООП. Речь идет об обертывании данных и кода в виде единого блока. В этом случае рекомендуется объявлять переменные как private а затем обращаться к ним через Getters и Setters для просмотра и / или изменения их.

public class Sample {
  private String  name;
  private int age;

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

Эти частные переменные не могут быть доступны непосредственно извне класса. Следовательно, они защищены от несанкционированного доступа. Но если вы хотите просмотреть или изменить их, вы можете использовать Getters и Setters.

getXxx() вернет текущее значение переменной xxx , в то время как вы можете установить значение переменной xxx с помощью setXxx() .

Соглашение об именах методов (в переменной example называется variableName ):

  • Все boolean переменные

     getVariableName()   //Getter, The variable name should start with uppercase
     setVariableName(..) //Setter, The variable name should start with uppercase
    
  • boolean переменные

      isVariableName()     //Getter, The variable name should start with uppercase
      setVariableName(...) //Setter, The variable name should start with uppercase
    

Публичные Getters и Setters являются частью определения свойства Java Bean.

Использование сеттера или геттера для реализации ограничения

Setters и Getters позволяют объекту содержать частные переменные, к которым можно получить доступ и изменить с ограничениями. Например,

public class Person {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if(name!=null && name.length()>2)
           this.name = name;
    }
}

В этом классе Person есть единственная переменная: name . К этой переменной можно обратиться с помощью getName() и изменить с помощью setName(String) , однако для установки имени требуется, чтобы новое имя имеет длину более 2 символов и не должно быть нулевым. Использование метода setter вместо того, чтобы публиковать name переменной, позволяет другим устанавливать значение name с определенными ограничениями. То же самое можно применить к методу геттера:

public String getName(){
   if(name.length()>16)
      return "Name is too large!";
   else
      return name;
}

В модифицированном getName() выше name возвращается, только если его длина меньше или равна 16. В противном случае возвращается "Name is too large" . Это позволяет программисту создавать переменные, которые достижимы и могут быть изменены, но, тем не менее, они препятствуют нежелательным редактированию переменных.

Зачем использовать Getters и Setters?

Рассмотрим базовый класс, содержащий объект с геттерами и сеттерами в Java:

public class CountHolder {
  private int count = 0;

  public int getCount() { return count; }
  public void setCount(int c) { count = c; }
}

Мы не можем получить доступ к переменной count потому что она закрыта. Но мы можем получить доступ к методам getCount() и setCount(int) потому что они общедоступны. Для некоторых это может поставить вопрос; зачем вводить посредника? Почему бы просто просто не считать их общедоступными?

public class CountHolder {
  public int count = 0;
}

Для всех целей и задач эти два являются точно такими же, функционально. Разница между ними - расширяемость. Подумайте, что говорит каждый класс:

  • Во-первых : «У меня есть метод, который даст вам значение int и метод, который установит это значение для другого int ».
  • Во-вторых : «У меня есть int который вы можете установить и получить, как пожелаете».

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

Давайте рассмотрим, хотим ли мы синхронизировать доступ к изменению и доступу к счету. Во-первых, это просто:

public class CountHolder {
  private int count = 0;

  public synchronized int getCount() { return count; }
  public synchronized void setCount(int c) { count = c; }
}

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

Поэтому он задает вопрос; являются ли общедоступные переменные когда-либо хорошей (или, по крайней мере, не злой)?

Я не уверен. С одной стороны, вы можете увидеть примеры открытых переменных, которые выдержали проверку времени (IE: переменная out ссылается System.out ). С другой стороны, предоставление публичной переменной не приносит пользы за пределы чрезвычайно минимальных накладных расходов и потенциального сокращения словесности. Мое руководство здесь будет состоять в том, что если вы планируете делать переменную публику, вы должны судить об этом против этих критериев с крайним предрассудком:

  1. Переменные не должны иметь никаких мыслимых оснований когда - либо изменений в его реализации. Это очень легко повредить (и, даже если вы все исправите, требования могут измениться), поэтому геттеры / сеттеры - общий подход. Если у вас будет общедоступная переменная, это действительно нужно продумать, особенно если она будет выпущена в библиотеке / framework / API.
  2. На переменную нужно ссылаться достаточно часто, чтобы гарантировать минимальный выигрыш от сокращения подробностей. Я даже не думаю, что накладные расходы на использование метода в сравнении с прямой ссылкой должны рассматриваться здесь. Это слишком незначительно для того, что я с консервативной оценкой должен составлять 99,9% приложений.

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



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow