자바는 public, private
같은 접근 제어자(access modifier)를 제공한다. 접근 제어자를 사용하면 해당 클래스 외부에서 특정 필드나 메서드에 접근하는 것을 허용하거나 제한할 수 있다.
이런 접근 제어자가 왜 필요할까?
스피커에 들어가는 소프트웨어를 개발하는 개발자라고 생각해보자. 스피커의 음량은 절대로 100을 넘으면 안된다는 요구사항이 있다.(100을 넘어가면 스피커가 고장난다고 가정하자)
Speaker
객체package access;
public class Speaker {
int volume;
Speaker(int volume) {
this.volume = volume;
}
void volumeUp() {
if (volume >= 100) {
System.out.println("음량을 증가할 수 없습니다. 최대 음량입니다.");
}
else {
volume += 10;
System.out.println("음량을 10 증가합니다.");
}
}
void volumeDown() {
volume -= 10;
System.out.println("volumeDown 호출");
}
void showVolume() {
System.out.println("현재 음량:" + volume);
}
}
위의 Speaker
객체에서 volumeUp
을 통해 볼륨을 올린다. 이 메서드를 통해 볼륨이 100이상 넘어가지 않도록 제어하고 있다.
새로운 개발자가 이 Speaker
객체를 사용한다고 해보자. 이때 새로운 개발자는 스피커가 100이상 넘어가면 스피커가 망가지는 것을 모른다. 새로운 개발자는 볼륨이 100이상 올라가지 않는 것을 보고 Speaker
클래스를 살펴본다. 이때 volume
필드를 직접 사용할 수 있기 때문에 새로운 개발자는 volume
필드에 직접 접근해 값을 200으로 설정하고 이 코드를 실행한 순간 스피커는 고장난다.
Speaker
객체를 사용하는 사용자는 Speaker
의 volume
필드와 메서드에 모두 접근할 수 있다.
앞서 volumeUp()
과 같은 메서드를 만들어서 음량이 100을 넘지 못하도록 제약을 걸어놨지만 소용이 없다. 왜냐하면 Speaker
를 사용하는 입장에서는 volume
필드에 직접 접근해서 원하는 값을 설정할 수 있기 때문이다.
이런 문제를 근본적으로 해결하기 위해서는 volume
필드의 외부 접근을 막을 수 있는 방법이 필요하다.
만약 Speaker
클래스를 개발하는 개발자가 처음부터 private
을 사용해서 volume
필드의 외부 접근을 막아두었다면 어떠했을까? 새로운 개발자도 volume
필드에 직접 접근하지 않고, volumeUp()
과 같은 메서드를 통해서 접근했을 것이다. 결과적으로 Speaker
가 망가지는 문제는 발생하지 않았을 것이다.
참고 : 좋은 프로그램은 무한한 자유도가 주어지는 프로그램이 아니라 적절한 제약을 제공하는 프로그램이다.
private
: 모든 외부 호출을 막는다.default
(pacakage-private) : 같은 패키지안에서 호출은 허용한다.