은닉성 (Encapsulation)

Jaemyeong Lee·2024년 12월 13일

게임 서버1

목록 보기
41/220

이 Step에서 다루는 것

  • 접근 지정자(public/protected/private)가 “문법”이 아니라 설계 도구인 이유
  • 데이터를 직접 열어두면 왜 유지보수/디버깅 비용이 폭발하는지(불변식 깨짐)
  • Getter/Setter를 “자동 생성”이 아니라 규칙을 한 곳에 모으는 창구로 쓰는 방법

학습 목표

  • public/protected/private를 “누가 접근 가능한가” 관점으로 설명할 수 있다.
  • “데이터는 숨기고(Encapsulate), 행동으로만 조작한다”의 의미를 예시로 설명할 수 있다.
  • protected가 왜 편하지만 위험할 수 있는지(상속 계층 결합) 감각을 가질 수 있다.

접근 지정자

접근 제어자설명
public누구나 접근 가능. 객체 외부에서 자유롭게 호출 가능
protected클래스 내부와 파생 클래스에서는 접근 가능, 외부에서는 불가능
private클래스 내부에서만 접근 가능. 외부 및 자식 클래스에서도 접근 불가능

핵심 요약:

  • public: “사용자가 눌러도 되는 버튼(인터페이스)”
  • private: “망가지면 큰일 나는 내부 구현/상태”
  • protected: “상속받은 코드가 내부에 손을 댈 수 있게 열어둔 문” (편하지만 결합도가 올라감)

자동차 비유

  • 핸들·페달 = public. 사용자가 조작.
  • 엔진·전기선 = private. 내부만. 막 건드리면 위험.

접근 지정자 시각화 (자동차 비유)

┌─────────────────────────────────────────────────────────────────────────────┐
│                    클래스 = 자동차                                             │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                               │
│   public (외부 접근 OK)          protected (자식만)        private (내부만)   │
│   ┌─────────────────┐            ┌─────────────┐          ┌─────────────┐  │
│   │  핸들 MoveHandle │            │  Dance()     │          │  엔진 분해   │  │
│   │  페달 StepPedal  │            │  (상속받은   │          │  전기선 연결 │  │
│   │  문 열기 OpenDoor│            │   자식만     │          │  연료 공급   │  │
│   │  (사용자 조작)   │            │   사용 가능) │          │  (위험·숨김) │  │
│   └─────────────────┘            └─────────────┘          └─────────────┘  │
│         ▲                                  ▲                       ▲         │
│    누구나 호출                        SuperCar::Test()        클래스 내부만   │
│                                                                               │
└─────────────────────────────────────────────────────────────────────────────┘

Getter/Setter, 캡슐화

  • _hpprivate으로 숨기고 SetHp()/GetHp() 같은 “창구”를 통해서만 접근하게 만들면,
    HP 규칙(불변식)부가 로직을 한 곳에 모을 수 있습니다.

예: HP는 일반적으로 이런 규칙을 가집니다.

  • (0 \le hp \le maxHp)
  • hp가 특정 임계치 아래로 내려가면 상태(버서커/위기/경고 UI)가 바뀐다

직접 _hp를 여기저기서 수정하게 두면,

  • 규칙이 여기저기 흩어져서 깨지기 쉽고
  • 버그가 났을 때 “누가 바꿨는지” 추적이 어렵습니다.
class Knight {
public:
    void SetHp(int hp)
    {
        // (예시) HP 규칙을 한 곳에 모음
        if (hp < 0)
            hp = 0;
        if (hp > _maxHp)
            hp = _maxHp;

        _hp = hp;

        if (_hp <= 50)
            SetBerserkerMode(); // 체력이 낮을 때 특수 모드 발동
    }

    int GetHp() const
    {
        return _hp;
    }

private:
    void SetBerserkerMode()
    {
        std::cout << "버서커 모드 발동!" << '\n';
    }

private:
    int _hp = 100;
    int _maxHp = 100;
};

직접 접근 vs 간접 접근

Knight k;
k._hp += 10;     // ❌ 오류! private 접근 불가
k.SetHp(40);     // ✅ Setter를 통해 값 설정 및 이벤트 처리

“직접 접근을 막는 것”이 귀찮아 보이지만, 규모가 커질수록 이게 디버깅/유지보수 난이도를 결정합니다.

상속 시 접근 지정자

  • class Knight : public Player → 공개적 상속. 부모가 준 것을 그대로 물려줌.
  • private 상속 → 자손에게 안 물려줌. (거의 사용 안 함)

체크 질문 (스스로 답해보기)

  • _hp를 public으로 열어두면 버그 추적이 어려워질까?
  • SetHp() 안에 “클램프/이벤트”를 넣는 장점은 무엇일까?
  • protected는 왜 편하지만, 상속 계층이 커질수록 위험해질까?

profile
李家네_공부방

0개의 댓글