[Java] getter, setter 메소드
1️⃣ getter, setter
- 왠만하면 멤버변수는
protected 되어 있습니다. getter 메소드를 이용하면 원하는 멤버변수의 정보를 얻을 수 있습니다.setter 메소드를 이용하면 원하는 멤버변수의 값으로 세팅해줄 수 있습니다.
< getter, setter 기본예시 >
public class main {
public static void main(String[] argc) {
member student1 = new member("Steve");
System.out.println(student1.getName());
student1.setName("Jane");
System.out.println(student1.getName());
}
}
class member {
protected String name;
public member(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
Steve
Jane
2️⃣ getter, setter 응용
(1) getter활용
- 아래에서 기존 멤버변수를 이용해서
멤버변수로 저장할 필요없이 계산한 값을 출력하도록 만들어 줄 수 있습니다.
class profile {
protected int height;
protected int weight;
public profile(int height, int weight) {
this.height = height;
this.weight = weight;
}
public double getBMI() {
return 10000 * this.weight / (this.height * this.height);
}
}
(2) setter활용1
- 특정조건일때만 입력을 받도록 만들어 줄 수 있습니다.
public class main {
public static void main(String[] argc) {
profile student1 = new profile("Mike", 26);
student1.setAge(111);
}
}
class profile {
/* 코드 생략 */
public void setAge(int age) {
if (age >= 1 && age <= 99)
this.age = age;
else
System.out.printf("setAgeError: not allowed (age %d)", age);
}
}
setAgeError: not allowed (age 111)
(3) setter활용2
- getter는 다소 자유롭게 사용해도 되지만 setter의 경우 값을 변경하는 것이기 때문에 아무 생각 없이 사용하면 위험할 수 있습니다.
- setter를 이용하여 멤버변수를 직접변경하는 것보다 setter를 이용하여 입력받은 값을 이용하여
객체 내부에서 알아서 멤버변수를 관리 해주도록 사용하면 조금 안전하게(객체를 좀 더 의미있게?) 사용할 수 있을 것 같습니다. - 아래의 코드예시는
score 를 입력받으면sum, mean 값을 객체내부에서 관리하는 코드입니다.
public class main {
public static void main(String[] argc) {
exam team1 = new exam(3); // 최대 인원수 3명으로 선언
if (!team1.setScore(10))
System.out.println("Error");
System.out.println("sum: " + team1.sum + " " + "mean: " + team1.mean);
if (!team1.setScore(20))
System.out.println("Error");
System.out.println("sum: " + team1.sum + " " + "mean: " + team1.mean);
if (!team1.setScore(30))
System.out.println("Error");
System.out.println("sum: " + team1.sum + " " + "mean: " + team1.mean);
if (!team1.setScore(40))
System.out.println("Error");
System.out.println("sum: " + team1.sum + " " + "mean: " + team1.mean);
}
}
class exam {
protected int index;
protected int indexMax;
protected int sum;
protected int mean;
protected int[] score;
/* 최대인원수만큼 배열 초기화 */
public exam(int maxPopulationMax) {
this.score = new int[populationMax];
this.indexMax = populationMax;
}
/* 점수만 추가 */
public boolean setScore(int score) {
if (score < 0 || this.index >= this.indexMax) {
return false;
} else {
this.score[this.index] = score;
updateSum(score);
updateMean();
index++;
return true;
}
}
/* sum과 mean은 객체가 알아서 관리 */
protected void updateSum(int score) {
this.sum += score;
}
protected void updateMean() {
this.mean = this.sum / (this.index + 1);
}
}
sum: 10 mean: 10
sum: 30 mean: 15
sum: 60 mean: 20
Error
sum: 60 mean: 20
3️⃣ 고찰
- setter를 사용할바에 멤버변수 자체를 public으로 만들면 되지 않을까 생각할 수 있지만 객체지향의 기준으로 생각해본다면 객체자체가 자기자신을 관리하는 것이 더 올바르기 때문에 setter를 사용하는 것이 캡슐화적으로도 맞다고 생각합니다. 또한 위의 예시처럼 getter, setter를 만들어 활용할 수 있습니다.
- 하지만 완벽한 캡슐화를 위해서는 되도록 setter는 고민하고 삽입하는 것이 좋을 것 같다고 생각합니다.
- getter는 마음대로 삽입해도 된다고 생각합니다. 하지만
immutable(불변) 클래스 를 제외한 클래스의 getter사용도 조심해야됩니다.
< 안좋은 getter예시 >
public static void main(String[] args) {
Test test = new Test();
ArrayList<Integer> sample = new ArrayList<>();
sample = test.getIntegers; // getter로 ArrayList개체를 받음
sample.add(3); // 수정이 가능하다.
}
- 위처럼 클래스를 반환하는 getter를 만들경우 수정이가능하기 때문에 잘 사용 해야 합니다.<b style=”font-size:85%”(단, String은 immutable클래스이기 때문에 가능하다.)</b>