📌 학습 목차
22-1. 캡슐화와 접근 제어자
22-2. 캡슐화와 접근 제어자 예제
22-1. 캡슐화와 접근 제어자
캡슐화(encapsulation): 객체의 멤버를 하나의 캡슐로 묶어 외부의 접근으로부터 실제 구현 내용을 감추는 것
Getter: 멤버 변수의 값을 반환하는 메서드 / 'get메서드 이름'으로 선언함
Setter: 매개 변수로 지정된 값을 검증해 유효한 경우에만 값을 변경하는 메서드 / 'set메서드 이름'으로 선언함
•객체의 멤버를 캡슐화하여 보호하는 이유는 외부의 잘못된 사용으로 인해 객체가 손상되지 않도록 하기 위함임
이때 자바에서는 캡슐화된 멤버를 보호하거나 외부 접근이 불필요한 멤버를 클래스 내부로 감추기 위해
클래스나 멤버, 주로 멤버에 접근 제어자를 사용하여 외부로부터의 직접 접근을 제한함
즉, 자바에서는 접근 제어자를 사용해 캡슐화를 구현함
1) 캡슐화된 멤버를 보호하기 위해 접근 제어자를 사용하는 경우
외부의 접근으로 인해 비밀번호와 같은 멤버 변수가 잘못된 값으로 변경되는 경우, 객체의 무결성(결점이 없는 성질)이 깨짐
이에 멤버 변수의 접근 제어자를 private 또는 protected로 지정해 외부로부터의 직접 접근을 제한하는 대신,
public 메서드인 Getter와 Setter를 제공해 멤버 변수에 대한 간접 접근만을 허용함으로써 캡슐화된 멤버를 보호함
2) 외부 접근이 불필요한 멤버를 클래스 내부로 감추기 위해 접근 제어자를 사용하는 경우
클래스 내부에서 임시로 사용되는 멤버 변수나 부분 작업을 처리하기 위한 메서드 등의 멤버는 외부 접근이 불필요함
이에 접근 제한자를 private으로 지정해 노출 제한함으로써 외부 접근이 불필요한 멤버를 클래스 내부로 감춤
22-2. 캡슐화와 접근 제어자 예제
// 1) 접근 제한자로 캡슐화를 구현하지 않은 경우
class Location {
📌 // 1-1) 멤버 변수의 접근 제한자가 default인 경우
int accuracy; // 0~10
double latitude;
double longitude;
}
public class Example {
public static void main(String[] args) {
Location l = new Location();
📌 // 1-2) 멤버 변수를 잘못된 값으로 변경하는 경우
l.accuracy = 100;
System.out.println(l.accuracy); // 100
}
1-1) 멤버 변수의 접근 제한자가 default인 경우
•멤버 변수 accuracy의 접근 제한자가 default인 경우,
Location 인스턴스를 생성한 후 같은 패키지 범위 내에서 멤버 변수에 직접 접근해 값을 임의로 변경할 수 있음
1-2) 멤버 변수를 잘못된 값으로 변경하려 하는 경우
•멤버 변수 accuracy가 0~10 사이의 값을 가져야 함을 가정할 때
같은 패키지 범위 내에서 멤버 변수를 100의 잘못된 값으로 변경하려 하는 경우, 이를 제한할 방법이 없음
// 2) 접근 제한자로 캡슐화를 구현한 경우
package chap_07;
class Location7 {
📌 // 2-1) 멤버 변수의 접근 제한자 변경
private int accuracy; // 0~10
private double latitude;
private double longitude;
📌 // 2-2) Getter 추가
public int getAccuracy() {
return accuracy;
}
📌 // 2-3) Setter 추가
public void setAccuracy(int accuracy) {
if (accuracy < 0 || accuracy > 10) {
return;
}
this.accuracy = accuracy;
}
}
public class _22_Example1 {
public static void main(String[] args) {
Location7 l = new Location7();
📌 // 2-4) 멤버 변수를 잘못된 값으로 변경하는 경우
l.setAccuracy(100);
System.out.println(l.getAccuracy()); // 0
}
}
2-1) 멤버 변수의 접근 제한자 변경 / 2-2) Getter 추가 / 2-3) Setter 추가
•멤버 변수 accuracy의 접근 제한자를 default에서 private으로 변경해 외부로부터의 직접 접근을 제한하는 대신,
public 메서드인 getAcurracy 메서드와 setAccuracy 메서드를 정의해 멤버 변수에 대한 간접 접근을 허용함
2-4) 멤버 변수를 잘못된 값으로 변경하려 하는 경우
•setAccuracy 메서드를 호출해 멤버 변수 accuracy를 100의 잘못된 값으로 변경하려 하는 경우,
멤버 변수에 대한 메서드 내부 조건이 충족되지 않아 값이 변경되지 않음
// 3) Setter 내부 조건식을 메서드로 정의할 경우
package chap_07;
class Location8 {
private int accuracy; // 0~10
private double latitude;
private double longitude;
public int getAccuracy() {
return accuracy;
}
public void setAccuracy(int accuracy) {
if (isNotValidAccuracy(accuracy)) {
return;
}
this.accuracy = accuracy;
}
📌 // 3-1) Setter 내부 조건식을 메서드로 정의
private boolean isNotValidAccuracy(int accuracy) {
return accuracy < 0 || accuracy > 10;
}
}
public class _22_Example2 {
public static void main(String[] args) {
Location8 l = new Location8();
l.setAccuracy(100);
System.out.println(l.getAccuracy()); // 0
}
}
3-1) Setter 내부 조건식을 메서드로 정의
•매개 변수로 넘겨받은 값이 유효한지 검증하는 isNotValidAccuracy 메서드를 정의해 조건식 의미를 더욱 명확하게 함
이때 반환 타입이 boolean인 Setter와 Getter의 이름은 is로 시작하는 것이 일반적임
•isNotValidAccuracy 메서드는 Location5 클래스 내부에서만 사용되므로, 접근 제한자를 public이 아닌 private으로 지정함
이처럼 메서드 정의 시 접근 제한자를 좁은 범위로 지정할 경우, 추후 메서드 변경에 대한 테스트 범위 또한 줄어듦
이에 접근 제어자의 범위는 최대한 좁게 설정한 후, 필요에 따라 점점 넓혀가는 것이 적절함
Reference
[남궁성의 정석코딩] Java의 정석 기초편 강의
[도우출판] Java의 정석 기초편 / 기본편
[한빛미디어] 이것이 자바다