Доступ к свойствам объекта (Get и Set)
На данный момент у нас есть два файла java — это Computer.java с вот таким содержимым
package testobject;
public class Computer {
public String name;
public int ram;
public int hdd;
public double weight;
public void on(){
int time;
System.out.println("Я включился. Моя модель " + name);
}
public void off(){
System.out.println("Я выключился");
}
public void load(){
System.out.println("Я загружаюсь. Мой объём жесткого диска равен " + hdd + " ГБ");
}
}
И файл MyFirstProgram.java с таким содержимым:
package myfirstprogram;
import testobject.Computer;
public class MyFirstProgram {
public static void main(String[] args) {
Computer comp = new Computer();
comp.name = "IBM";
comp.hdd = 350;
comp.on();
comp.load();
comp.off();
}
}
Сегодня мы рассмотрим доступ к свойствам объекта при помощи так называемых «гетеров» и «сетеров». В прошлом уроке мы создали у объекта Computer несколько характеристик: public String name; public int ram; public int hdd; public double weight; Всё это, как вы помните, свойства объекта или ещё говорят переменные класса. Обратите внимание, что наши переменные класса используют модификатор доступа public.
Однако следует помнить, что использовать модификатор доступа public в полях класса не безопасно. Любой, кто использует объект, может напрямую изменить свойство объекта. Например, такие свойства, как объём жесткого диска, количество оперативной памяти, вес — не могут быть меньше 0. Но сейчас мы можем присвоить им отрицательные значения, так как наши переменные имеют модификатор доступа public. (comp.hdd = -100;)
Если допустить несанкционированный доступ к свойствам, то впоследствии наш объект может повести себя неадекватно.
ВЫВОДЫ
— От состояния объекта (значений переменных класса) зависит правильная работа объекта. Мы должны разрешить менять переменные так, чтобы после этого объект продолжал работать правильно.
— Задача — обеспечить безопасность изменения состояния объекта (безопасность изменения переменных класса).
Поэтому для защита был придуман механизм доступа к свойствам объекта с помощью get и set
В гетерах реализуют дополнительные действия, к примеру проверка значения или преобразование значения.
get — получить значение.
set — передать значение.
В коде представляют собой обычные методы, но имя, как правило, начинается с префиксом get или set, чтобы было понятней. К примеру getName и setName.
Таким образом мы обеспечиваем безопасность на запись значения переменной и на получение значения переменной. Также следует учитывать как можно больше факторов, которые могут «поломать» объект. Теперь рассмотрим как это будет выглядеть в программном коде.
1) Вернитесь в файл Computer.java
2) Измените модификаторы доступа в полях класса с public на private (доступный только внутри своего класса)
private String name;
private int ram;
private int hdd;
private double weight;
Теперь доступ к нашим переменным извне класса закрыт. Теперь следует организовать доступ через «гетеры» и «сетеры.» Начнём с переменной name. Для того, чтобы имелась возможность получить значение переменной name, мы создадим метод getName с модификатором доступа public.
public String getName(){
return name;
}
После Public мы указали ТИП ВОЗВРАЩАЕМОГО ЗНАЧЕНИЯ (String, поскольку будем передавать название).
Правило наименование «гетеров» — сначала пишем get потом Name — getName. Данный метод не имеет параметров — скобки оставляем пустые getName() В фигурных скобках для того, чтобы возвратить значение требуется ключевое слово return, то есть возврат. А возвращать мы будем значение переменной name.
Даже если у переменной модификатор доступа private — как мы помним она всё равно доступна внутри класса, плюс во всех методах этого класса. Внутри метода getName переменная name нам доступна на прямую. Если мы зажмём клавишу ctrl и щелкнем ЛКМ (Левой Кнопкой Мыши) по name внутри метода, то Netbeans нам покажет какую именно переменную мы возвращаем.
Теперь создадим «сетер».
public void setName(String newName){
name = newName;
}
Модификатор доступа у нас будет public. Тип метода будет не String, а void, поскольку метод ничего не будет возвращать. Правило наименование «сетера» у нас set и название метода (setName), в качестве параметра метода мы передаём переменную, которая совпадает с ТИПОМ ПЕРЕМЕННОЙ NAME (String newName). Теперь открываем фигурные скобки и внутри этого метода мы должны присвоить нашей переменной name новое значение. То есть мы пишем name = newName;
Получается, что в переменную класса мы записали переданный параметр newName.
«Гетер» и «сетер» для одной переменной name создан. Давайте сделаем тоже самое для переменной ram (оперативная память).
public int getRam(){
return ram;
}
По аналогии пишем public, только тип метода у нас уже будет не String, а int.
public void setRam(int newRam){
ram = newRam;
}
Тип метода будет void, поскольку «сетер» ничего не возвращает, а только меняет значение переменной ram.
Теперь давайте защитим наши переменные от неправильных значений. К примеру значение оперативной памяти не может быть отрицательным. Поэтому в методе setRam, перед тем, как задать значение ram — мы должны поставить проверку. Явялется ли значение newRam положительным? Для этого нам нужно создать условие (ветвление) по аналогии с дургими языками программирования. if — если, else — иначе.
public void setRam(int newRam){
if(newRam>0){
ram = newRam;
} else {
System.out.println("Переданное значение " +newRam+ "не может быть отрицательным!");
}
}
Если переданное значение (newRam) больше ноля, тогда мы присвоим значение newRam переменной ram, иначе мы выводим на экран сообщение о том, что переданное значение не может быть отрицательным. Перед каждым выводом сообщения будет определяться значение newRam и она будет вставляться в наш текст.
По аналогии можно сделать такую же проверку для переменных hdd (объём жесткого диска) и weight (вес), чтобы при работе с объектом Computer мы могли задавать только корректное значение этих переменных.
public void setHdd(int newHdd){
if(newHdd>0){
hdd = newHdd;
} else {
System.out.println("Переданное значение " +newHdd+ "не может быть отрицательным!");
}
}
public void setWeight(int newWeight){
if(newWeight>0){
weight = newWeight;
} else {
System.out.println("Переданное значение " +newWeight+ "не может быть отрицательным!");
}
}
Теперь вернёмся в файл MyFirstProgram.java
package myfirstprogram;
import testobject.Computer;
public class MyFirstProgram {
public static void main(String[] args) {
Computer comp = new Computer();
comp.name = "IBM";
comp.hdd = 350;
comp.on();
comp.load();
comp.off();
}
}
Теперь нам недоступны переменные объекта Computer напрямую, как мы это делали в прошлом уроке. У нас доступны только методы с модифкаторами public («гетеры,» «сетеры,» on(), off() и т.д.) Напрямую мы к переменным обращаться не можем. Присвоем значение переменной name при помощи «сетера.»
1) Вместо comp.name = «IBM»; напишите comp.setName(«IBM»);
2) Вместо comp.hdd = 320; напишите comp.setHdd(320);
3) Добавьте также значение для оперативной памяти — comp.setRam(2048);
package myfirstprogram;
import testobject.Computer;
public class MyFirstProgram {
public static void main(String[] args) {
Computer comp = new Computer();
comp.setName("IBM");
comp.setRam(2048);
comp.setHdd(320);
comp.on();
comp.load();
comp.off();
}
}
Запустим нашу программу:
run:
Я включился. Моя модель IBM
Я загружаюсь. Мой объём жесткого диска равен 320 ГБ
Я выключился
СБОРКА УСПЕШНО ЗАВЕРШЕНА (общее время: 0 секунд)
Присвоение переменных прошло корректно.
Если мы присвоим отрицательное значение comp.setHdd(-320); программа перехватит его и выведет сообщение, что переданное значение не может быть отрицательным.
Переданное значение -320 не может быть отрицательным!
Я включился. Моя модель IBM
Я загружаюсь. Мой объём жесткого диска равен 0 ГБ
Я выключился
СБОРКА УСПЕШНО ЗАВЕРШЕНА (общее время: 0 секунд)
Таким образом мы предотвратили неправильное присвоение переменным нашего объекта и защитили его от небезопасного обращения на прямую к переменным (полям) класса.
Итак файл MyFirstProgram.java выглядит примерно так:
package myfirstprogram;
import testobject.Computer;
public class MyFirstProgram {
public static void main(String[] args) {
Computer comp = new Computer();
comp.setName("IBM");
comp.setRam(2048);
comp.setHdd(-320);
comp.on();
comp.load();
comp.off();
}
}
А файл Computer.java так:
package testobject;
public class Computer {
private String name;
private int ram;
private int hdd;
private double weight;
public String getName(){
return name;
}
public void setName(String newName){
name = newName;
}
public int getRam(){
return ram;
}
public void setRam(int newRam){
if(newRam>0){
ram = newRam;
} else {
System.out.println("Переданное значение " +newRam+ " не может быть отрицательным!");
}
}
public void setHdd(int newHdd){
if(newHdd>0){
hdd = newHdd;
} else {
System.out.println("Переданное значение " +newHdd+ " не может быть отрицательным!");
}
}
public void setWeight(int newWeight){
if(newWeight>0){
weight = newWeight;
} else {
System.out.println("Переданное значение " +newWeight+ "не может быть отрицательным!");
}
}
public void on(){
int time;
System.out.println("Я включился. Моя модель " + name);
}
public void off(){
System.out.println("Я выключился");
}
public void load(){
System.out.println("Я загружаюсь. Мой объём жесткого диска равен " + hdd + " ГБ");
}
}

