Menu
Coddy logo textTech

캡슐화란 무엇인가요?

객체지향 프로그래밍에서 캡슐화(encapsulation)는 객체의 데이터와 그 데이터를 다루는 메서드를 보통 클래스라는 하나의 단위로 묶고, 내부 세부 사항을 숨겨서 다른 코드가 공개된 메서드를 통해서만 객체를 사용하게 하는 것입니다.

글쓴이: Kevin Spektor, 공동 창업자, CTO

업데이트: 2026년 9월 24일

은행 앱이 각 계좌의 잔액을 평범한 변수에 저장한다고 해 볼게요. 프로그램 어디서든 어떤 줄이 account.balance = -500이라고 쓸 수 있고, 아무것도 이를 막지 못해요. 운영 환경에서 음수 잔액이 나타나면 코드 전체를 뒤져서 잔액을 건드린 곳을 모두 찾아야 해요. 캡슐화가 이 문제를 해결해요. 잔액은 몇 개의 메서드를 통해서만 바뀔 수 있고, 그 메서드들이 출금액이 잔액을 넘을 수 없다는 것 같은 규칙을 강제해요.

캡슐화는 어떻게 동작하나요

캡슐화는 두 가지 개념을 합친 거예요.

  1. 묶기. 데이터(잔액)와 그 데이터를 다루는 코드(입금, 출금)가 같은 클래스 안에 있어요.
  2. 숨기기. 다른 코드는 클래스의 공개 인터페이스만 봐요. 그 뒤의 데이터는 내부의 것이므로 클래스가 허용하는 방식으로만 바뀔 수 있어요.

클래스가 지키는 규칙을 불변식(invariant)이라고 해요. 여기서는 "잔액은 절대 음수가 아니다"예요. 모든 변경이 클래스의 메서드를 거치므로, 프로그램의 나머지 부분이 무엇을 하든 불변식은 유지돼요.

70
refused: not enough money

바깥 코드는 acct.balance를 읽을 수 있지만, 이 프로퍼티에는 setter가 없으므로 acct.balance = 1000은 AttributeError를 발생시켜요. 잔액이 틀렸다면 살펴볼 메서드는 정확히 두 개예요.

Python의 캡슐화

Python에는 private 키워드가 없어요. 대신 모든 Python 프로그래머가 아는 이름 규칙에 기대요.

  • name: 공개, 인터페이스의 일부예요.
  • _name: 내부용이에요. 읽는 것을 막지는 않지만, 앞의 밑줄은 "여기에 의존하지 마세요"라는 뜻이에요.
  • __name: Python이 클래스 안에서 이름을 바꿔 버리므로(네임 맹글링), 하위 클래스가 실수로 덮어쓸 수 없어요.
  • @property: 메서드를 속성처럼 읽히게 만들어, 나중에 호출하는 코드를 바꾸지 않고도 검사를 추가할 수 있어요.
0
False
42

네임 맹글링은 접근이 아니라 실수를 막아요. 바뀐 이름으로는 여전히 접근할 수 있어요. Python은 프로그래머가 밑줄을 존중하리라 믿어요. 실제로 대부분의 Python 코드는 밑줄 하나와 @property를 쓰고, 밑줄 두 개는 상속을 염두에 둔 클래스에만 써요. 클래스 작성법은 Python 클래스 문서에서 더 볼 수 있어요.

Java, C++, JavaScript의 캡슐화

다른 언어는 숨기기를 강제해요. Java에서 private 필드는 자기 클래스 안에서만 쓸 수 있어요.

public class BankAccount {
    private int balance;  // hidden from every other class

    public int getBalance() { return balance; }

    public void withdraw(int amount) {
        if (amount > balance) throw new IllegalArgumentException("not enough money");
        balance -= amount;
    }
}

다른 클래스에서 account.balance = 1000;이라고 쓰면 컴파일되지 않아요. javac가 balance has private access in BankAccount를 보고해요.

언어숨긴 멤버공개 멤버강제하는 주체
Python_name, __namename관례
Javaprivate int namepublic int name컴파일러
C++private: 구역public: 구역컴파일러
JavaScript#namenameJavaScript 엔진

C++는 class 멤버를 기본으로 private으로, struct 멤버를 public으로 만들어요. ES2022에 추가된 JavaScript의 # private 필드는 클래스 밖에서 아예 읽을 수 없어요. 각각 문서에서 다뤄요. Java 접근 제어자, C++ 접근 지정자, JavaScript private 필드를 참고하세요.

캡슐화가 중요한 이유

  • 규칙이 한곳에 있어요. "잔액보다 많이 출금할 수 없다"는 검사를 프로그램의 모든 출금 앞이 아니라 withdraw 안에 한 번만 써요.
  • 내부를 자유롭게 바꿀 수 있어요. 돈을 float 대신 센트 단위 정수로 저장하기로 해도 클래스만 바뀌어요. deposit(100)을 호출하는 코드는 그대로 동작해요.
  • 디버깅이 쉬워져요. 값이 틀렸을 때 용의자는 프로그램의 모든 줄이 아니라 그 값을 바꿀 수 있는 몇 개의 메서드예요.
  • 배우고 테스트할 것이 줄어들어요. 공개 메서드가 세 개인 클래스는 그 세 메서드로 이해하고 테스트할 수 있어요.

캡슐화는 클래스보다 큰 단위에서도 통해요. 함수 두 개를 공개하고 보조 함수 열 개를 내부에 두는 모듈도 같은 방식으로 캡슐화된 것이고, 프로그램이 시스템 호출을 통해서만 파일을 열게 하는 운영체제도 마찬가지예요.

캡슐화는 추상화와 자주 혼동돼요. 추상화는 인터페이스가 무엇을 제공할지 정하고, 캡슐화는 그 뒤의 데이터를 보호해요. 추상화 페이지에 둘을 나란히 놓은 비교가 있어요. 다형성, 상속과 함께 이들은 객체지향 프로그래밍의 네 기둥이에요.

흔한 실수

  • 모든 필드에 getter와 setter 만들기. 어떤 숫자든 받아들이는 setBalance는 아무것도 보호하지 않아요. 각 필드에 대한 날것의 접근이 아니라 객체에 필요한 연산(withdraw)을 제공하세요.
  • 내부 객체 반환하기. self._items를 반환하는 메서드는 호출한 쪽에 진짜 리스트를 넘겨주고, 그쪽에서 리스트를 바꿀 수 있게 돼요. 대신 사본이나 튜플을 반환하세요.
  • private을 보안으로 여기기. 접근 제어자는 실수를 막을 뿐 공격을 막지는 않아요. Java 코드는 리플렉션으로 private 필드를 읽을 수 있고, Python 코드는 _name을 바로 읽을 수 있어요. 비밀번호와 키는 해싱과 암호화 같은 진짜 보호가 필요해요.

다음 단계

다음으로 두 개념의 차이를 다루는 추상화를 읽고, 이어서 다형성을 읽어 보세요. Python 강좌에서는 클래스를 단계별로 만들어 보고, Java 강좌에서는 컴파일러가 강제하는 캡슐화를 볼 수 있어요.

자주 묻는 질문

캡슐화를 쉽게 설명하면 무엇인가요?
캡슐화는 객체가 자기 데이터를 스스로 간직하고, 그것을 사용하는 안전한 방법 몇 가지만 제공하는 거예요. 은행 계좌 객체는 새 잔액을 직접 입력하게 두지 않고, 먼저 규칙을 확인하는 deposit과 withdraw를 제공해요. 이름은 내용물을 안에 가둬 두는 껍질인 캡슐에서 왔어요.
캡슐화의 예로는 어떤 것이 있나요?
deposit과 withdraw를 통해서만 변경을 허용하는 은행 계좌 클래스가 대표적인 예예요. Python의 list도 예예요. append를 호출할 뿐, 항목을 저장하는 메모리를 직접 관리하지 않아요. 함수 몇 개만 공개하고 보조 함수는 내부에 두는 모듈은 더 큰 규모의 캡슐화예요.
캡슐화의 세 가지 종류는 무엇인가요?
세 가지로 나누는 튜토리얼은 보통 멤버 변수 캡슐화(private 필드), 함수 캡슐화(private 보조 메서드), 클래스 캡슐화(다른 클래스나 모듈 안에 숨긴 클래스)를 말해요. 공식적인 분류는 아니고, 같은 개념을 필드, 메서드, 클래스 전체에 적용한 거예요.
C++에서 캡슐화는 무엇이고 어떻게 쓰나요?
C++에서는 데이터 멤버를 private으로 표시하고, 이를 읽거나 바꾸는 public 멤버 함수를 제공해요. class의 멤버는 기본이 private이고, struct의 멤버는 기본이 public이에요. 컴파일러는 클래스 밖에서 private 멤버를 쓰려는 코드를 거부해요.
네트워크에서 캡슐화는 무슨 뜻인가요?
네트워크에서 캡슐화는 데이터가 나가는 길에 각 프로토콜 계층의 헤더로 감싸는 것을 뜻해요. HTTP 메시지는 TCP 세그먼트 안에, TCP 세그먼트는 IP 패킷 안에, IP 패킷은 이더넷 프레임 안에 들어가요. 프로그래밍의 캡슐화와 이름은 같지만 다른 개념이에요.
Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기