7.5 캡슐화와 접근 제어자 (Encapsulation & Access Modifiers)
객체지향 프로그래밍에서 캡슐화(Encapsulation) 란 클래스의 데이터(변수)와 실제 데이터를 처리하는 메서드를 하나의 단위로 묶고, 중요한 내부 데이터를 외부에서 함부로 접근하지 못하도록 숨기는 것을 말합니다. 이를 정보 은닉(Information Hiding) 이라고도 부릅니다.
마치 감기약 캡슐이 쓰디쓴 약가루를 포장하여 환자가 약을 안전하고 편하게 넘길 수 있도록 돕는 것과 같은 원리입니다. 자바에서는 이를 접근 제어자(Access Modifiers) 로 제어합니다.
1. 접근 제어자의 종류
접근 제어자는 멤버(변수, 메서드)나 클래스 선언 시 사용되어, 해당 멤버에 접근할 수 있는 범위를 제한합니다. 보안 및 데이터 무결성 유지를 위해 필수적입니다. 자바의 접근 제어자 4가지는 다음과 같습니다 (접근 범위가 넓은 순서대로 나열):
| 제어자 명 | 접근 권한 설명 | 접근 범위 (가시성) |
|---|---|---|
public | 접근에 제한이 없습니다. 어디서든 사용 가능합니다. | 전체 접근 허용 |
protected | 같은 패키지 는 물론, 다른 패키지의 자식 클래스 에서도 접근 가능합니다. | 패키지 내 + 상속 관계 |
(default) | 아무런 키워드도 안 쓴 상태. 같은 패키지 내 에서만 접근 가능합니다. | 패키지 내 |
private | 오직 선언된 같은 클래스 내 에서만 접근 가능합니다! 가장 좁은 범위. | 클래스 내부 전용 |
팁: 실무 관례상 보통 클래스의 상태값(멤버 변수)은 무조건
private으로 선언하여 외부의 직접 접근을 막습니다.
2. 캡슐화의 적용 - Getter와 Setter
그렇다면 변수가 private으로 막혀있을 때 외부 클래스에서는 이 데이터를 어떻게 읽거나 수정할까요? 바로 public으로 선언된 메서드 를 통해서만 간접적으로 접근하도록 만듭니다. 우리는 이런 메서드들을 Getter와 Setter라고 부릅니다.
public class Person {
// 1. 모든 변수는 private로 철저히 숨깁니다.
private String name;
private int age;
// 2. 값 설정 전용 메서드 Setter (외부에서 값을 넣을 때 호출)
public void setAge(int age) {
// 유효성 검사 로직을 추가할 수 있습니다!
if (age < 0 || age > 150) {
System.out.println("오류: 올바르지 않은 나이입니다.");
return;
}
this.age = age;
}
// 3. 값 반환 전용 메서드 Getter (외부에서 값을 읽을 때 호출)
public int getAge() {
return this.age;
}
// Setter
public void setName(String name) {
this.name = name;
}
// Getter
public String getName() {
return this.name;
}
}
public class EncapsulationExample {
public static void main(String[] args) {
Person p = new Person();
// p.age = -50; // 에러 발생! private 필드 객체 밖에서 접근 불가
p.setAge(-50); // Setter 메서드 활용: "오류: 올바르지 않은 나이입니다." 출력
p.setAge(25); // 올바른 데이터는 통과되어 저장
System.out.println("이 사람의 나이는: " + p.getAge());
}
}
왜 Getter와 Setter를 쓰나요?
- 데이터 무결성(검증): 위의
age예시처럼, 나이에-50살이나 숫자가 아닌 값이 들어오는 것을 메서드 내부에서if문으로 사전에 차단할 수 있습니다. 무분별하게 변수가 오염되는 것을 막습니다. - 읽기 전용 만들기:
Setter를 아예 만들지 않고Getter만 만들면, 외부에서는 데이터를 절대 변경할 수 없는 ** 읽기 전용 객체**를 만들 수도 있습니다. - 내부 구현 숨기기: 외부에선 껍데기 메서드만 호출하게 두고, 내부에서 나이를 계산하는 공식이 바뀌더라도
Person밖의 메인 코드는 수정할 필요가 없어져 유지보수가 좋아집니다.
마치며
이로써 객체지향 프로그래밍(OOP)의 4대 핵심인 상속(Inheritance), 다형성(Polymorphism), 추상화(Abstraction), 캡슐화(Encapsulation)에 대해 모두 알아보았습니다. 처음에는 단어들이 너무 이론적이고 추상적으로 느껴질 수 있지만, 이 개념들은 앞으로 등장할 디자인 패턴이나 프레임워크(Spring Boot 등)를 다루기 위해 반드시 거쳐야 할 필수 코스입니다.