MSM8994의 화룡점정 블로그

[JAVA] 멤버 변수를 보호해주는 Getter와 Setter 본문

코딩

[JAVA] 멤버 변수를 보호해주는 Getter와 Setter

msm8994 2018. 7. 20. 07:00

클래스에 소속될 멤버 변수를 선언하실 때 무심코 아래와 같이 만드는 경우가 있을 겁니다.


public int score = -1; // 학생의 점수를 기억 (-1: 입력되지 않음)

그리고 접근할 때 아래처럼 하시겠죠.


student[i].score = inputScore; // 가장 간단히 멤버 변수 값을 바꾸는 법

이렇게 하는 것이 가장 간단하기 때문일겁니다.


그러면 입력될 점수에 유효범위가 필요할 때는 어떻게 하면 좋을까요?

if(0 <= inputScore && inputScore <= 100){
    // 값을 바꾸기 전 조건을 준다
    student[i].score = inputScore;
}

이렇게 감싸는 것만이 답일까요. 이렇게 객체가 쓰이는 곳에서 검증을 하게 된다면 코드 분량이 많아집니다. 같은 분량을 다른 곳에도 계속 붙여넣기 하면 나중에 이 기준을 바꿔야할 때 모든 곳에 찾아가서 바꿔야하는 불편이 생기게 됩니다. 혹은 다른 개발자가 저걸 모른 채로 어떤 값을 그대로 넣는다면 이를 막을 수 없습니다.





Setter

그래서 Setter를 쓰기 시작했습니다. Setter는 어떤 멤버 변수에 값을 주기 위해 만든 메소드입니다. 이 메소드 하나만 사용하면 값의 기준을 바꿔도 한 군데만 바꾸면 간단히 해결되죠.

public boolean setScore(int score){
    // 값을 바꾸기 전 조건을 준다
    if(0 <= score && score <= 100){
        this.score = score;
        return true; // 값을 바꿀 수 있었습니다
    } else {
        return false; // 값을 바꾸지 못했습니다
    }
}

이렇게 하면 클래스 내에서 값 설정에 조건을 걸 수 있게 됩니다. return으로 반환값을 주면 멤버변수에 이 값을 제대로 줄 수 있었는지도 알 수 있겠네요.(반환값을 boolean으로 하는 대신 int로 바꾸면 성공 실패가 아니라 세분화된 오류코드를 제시할 수도 있겠네요)


if(student[i].setScore(inputScore)){
    System.out.println(inputScore + "점이 성공적으로 반영됨.");
} else {
    System.out.println(inputScore + "점을 반영하지 못함.");
}

이렇게 조건을 한 곳에서 통제할 수 있는 방법을 알아봤습니다.



Getter

그럼 다른 클래스에서 이 값을 마음대로 바꾸지 못하게 하려면 public 대신 private 로 선언하면 되는 것은 알고 계셨죠?

private int score = 0; // 학생의 점수를 기억 (-1: 입력되지 않음)
이 값을 다른 클래스에서 읽고 싶을 때도 있는데 이렇게 접근을 막아버리면 답답하실거에요.
그럴 때 필요한 것이 Getter 입니다.
Getter는 어떤 멤버 변수의 값을 가져올 때 쓰는 메소드 입니다. 직접 접근하는 것은 막혀있으니 이렇게 가져올 수 밖에 없습니다.


public int getScore(){
    // 학생의 점수를 반환
    return this.score;
}

쓸 때는 이렇게 가져오면 됩니다.


switch(student[i].getScore()/10){
    case 10:
    case  9:
        // 100점~90점대 A
        System.out.println("A");
        break;
    case  8:
        // 80점대 B
        System.out.println("B");
        break;
    case  7:
        // 70점대 C
        System.out.println("C");
        break;
    case  6:
        // 60점대 D
        System.out.println("D");
        break;
    default:
        // 그 밖의 값은 F
        System.out.println("F");
        break;
}


맺음말

클래스 안에 private로 멤버 변수를 숨기고 public으로 개방된 메소드를 통해 이 변수에 간접적으로 접근하는 방법에 대해 알아봤습니다. Getter와 Setter는 보통 public으로 선언하지만 필요에 따라 Setter를 private 등으로 선언하기도 합니다.
Android Studio나 IntelliJ IDEA 같은 일부 개발 도구에서는 같은 클래스에서 Getter Setter 쓰는게 비효율적이라고 태클을 걸기도 합니다. 맞는 말입니다. Getter와 Setter를 쓰는건 메소드 호출 및 복귀로 인해 직접 접근하는 것보다 조금 느립니다. 특히 값을 단순히 반환하기만 하는 Getter가 Setter에 비해 필요성이 많이 적기도 합니다. 하지만 통제를 하기 위해 멤버 변수를 숨기고 메소드만 열어둔 만큼 어쩔 수 없는 선택입니다. C#에서는 속성이라는 개념을 통해 멤버 변수의 대리자 역할을 하며 자바보다 Getter와 Setter 써먹기가 더 쉽습니다. 여기서 소개하도록 할게요.

Comments