Java Language
Геттеры и сеттеры
Поиск…
Вступление
Добавление геттеров и сеттеров
Инкапсуляция является базовой концепцией в ООП. Речь идет об обертывании данных и кода в виде единого блока. В этом случае рекомендуется объявлять переменные как 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
). С другой стороны, предоставление публичной переменной не приносит пользы за пределы чрезвычайно минимальных накладных расходов и потенциального сокращения словесности. Мое руководство здесь будет состоять в том, что если вы планируете делать переменную публику, вы должны судить об этом против этих критериев с крайним предрассудком:
- Переменные не должны иметь никаких мыслимых оснований когда - либо изменений в его реализации. Это очень легко повредить (и, даже если вы все исправите, требования могут измениться), поэтому геттеры / сеттеры - общий подход. Если у вас будет общедоступная переменная, это действительно нужно продумать, особенно если она будет выпущена в библиотеке / framework / API.
- На переменную нужно ссылаться достаточно часто, чтобы гарантировать минимальный выигрыш от сокращения подробностей. Я даже не думаю, что накладные расходы на использование метода в сравнении с прямой ссылкой должны рассматриваться здесь. Это слишком незначительно для того, что я с консервативной оценкой должен составлять 99,9% приложений.
Там, наверное, больше, чем я не рассматривал с головы. Если вы когда-либо сомневаетесь, всегда используйте геттеры / сеттеры.