이번에는 객체지향의 특징인 정보은닉에 대해서 알아보겠습니다.
정보은닉이란 클래스 내부에서 사용할 값을 외부에서 접근하지 못하게 함으로써
데이터를 변조하지 못하게 하는것입니다.
여기까지만 들었을때는 정보은닉을 굳이 해야하나? 라는 생각이 드실텐데
예시 코드를 살펴보면서 알아보겠습니다.
class Score {
int score = 0; // 시험점수
public Score(int score) {
setScore(score);
}
public void setScore(int s) {
if(score < 0 || score > 100) {
score = 0;
return;
}
score = s;
}
public int getScore() {
return score;
}
}
위의 코드는 시험점수를 기록하는 클래스입니다. 시험점수는 0 ~ 100점 사이에서만 기록을 할 수 있습니다. 문제는 위의 코드를 바탕으로 아래의 main문을 실행했을 때 발생합니다.
public static void main(String args[]) {
Score s = new Score(80);
System.out.println(s.getScore()); // 80
s.setScore(60);
System.out.println(s.getScore()); // 60
s.setScore(-10);
System.out.println(s.getScore()); // 0
s.Score = -40;
System.out.println(s.getScore()); // 컴파일 오류 발생 안함
}
Score클래스에서 점수는 0~100점까지만 대입이 가능하게 만들었으나 main문에서 -40을 넣을때 오류가 나지않고 -40이라는 의도와는 다른 결과값이 나오게 됩니다. 정보은닉을 하지 않음으로써 다른 클래스에서 직접적으로 변수를 조작할 수 있다는 문제점이 발생한것입니다.
이런 문제점을 해결하기 위해서 정보은닉이라는 기법을 사용합니다.
정보은닉의 핵심은 바로 접근제한자를 설정해서 다른 클래스에서 정보를 직접적으로 변경하지 못하게합니다.
그럼 바로 정보은닉을 적용하여 코드를 작성해보면 아래와 같이 나오게됩니다.
class Score {
private int score = 0;
public Score(int score) {
setScore(score);
}
public void setScore(int s) {
if(score < 0 || score > 100) {
score = 0;
return;
}
score = s;
}
public int getScore() {
return score;
}
}
정보은닉을 적용해야할 점은 크게 두가지 입니다.
- 변수에 private 접근제한 설정
- getter와 setter 설정
첫 번째로는 변수에 private 접근제한자를 설정하여 외부 클래스에서의 접근을 차단하고 현재 클래스에서만 데이터를 변경할 수 있게 설정합니다.
두 번째는 getter와 setter를 만들어 외부에서 데이터를 조작할 수 있게 만드는 것입니다.
정보은닉을 위해서 우리는 클래스자체가 아닌 '변수'에만 접근을 제한했습니다. 따라서 변수를 변경하기 위해서 다른 클래스에서 직접적으로 변경이 아닌 우리가 만든 setter라는 메소드로만 값을 변경하고 getter라는 메소드로만 값을 가져올수 있게 만들어줘야 합니다.
public void setScore(int s) {
if(score < 0 || score > 100) {
score = 0;
return;
}
score = s;
}
public int getScore() {
return score;
}