본문 바로가기
카테고리 없음

C# 캡슐화(Encapsulation) 완벽 정리!🚀 | public, private, protected 차이까지!

by bbongz 2025. 3. 2.

 

C#을 배우면서 캡슐화(Encapsulation) 라는 개념을 들어본 적이 있으신가요?
캡슐화는 객체 지향 프로그래밍(OOP)의 핵심 개념 중 하나로, 데이터를 보호하고 코드의 안정성을 높이는 중요한 기능입니다.

 

이 글에서는 캡슐화의 개념, public, private, protected 접근 제한자의 차이를 쉽고 자세한 예제와 함께 설명해 드릴게요! 😊


🔹 캡슐화(Encapsulation)란?

💡 캡슐화(Encapsulation)클래스 내부의 데이터(변수)를 외부에서 직접 접근하지 못하게 보호하는 것입니다.

 

📌 캡슐화의 핵심 목표
✅ 외부에서 데이터(변수)를 직접 변경하지 못하도록 보호
✅ getter 및 setter 메서드를 제공하여 안전하게 데이터 조작 가능
✅ 코드 유지보수성을 높이고, 오류를 방지

📌 캡슐화 예제 (잘못된 코드 - 캡슐화 적용 전)

using System;

class BankAccount
{
    public int balance;  // 🔴 누구나 직접 접근 가능 (위험!)

    public void Withdraw(int amount)
    {
        balance -= amount;
    }
}

class Program
{
    static void Main()
    {
        BankAccount account = new BankAccount();
        account.balance = -1000;  // ❌ 직접 접근 가능 (잘못된 값 입력 가능)
        Console.WriteLine($"잔액: {account.balance}");
    }
}

🔍 실행 결과 (잘못된 데이터 입력)

잔액: -1000

 

💡 문제점

  • balance가 public으로 선언되어 누구나 직접 접근 가능
  • 잘못된 값(예: -1000)을 입력해도 막을 방법이 없음

이제 캡슐화를 적용하여 해결해 보겠습니다!


🔹 private를 활용한 캡슐화 적용 ✅

변수를 private으로 선언하고, getter 및 setter 메서드를 사용하여 안전하게 접근하도록 변경

using System;

class BankAccount
{
    private int balance;  // 🔒 외부에서 직접 접근 불가능

    // 생성자 (초기 잔액 설정)
    public BankAccount(int initialBalance)
    {
        balance = initialBalance;
    }

    // 잔액 조회 (getter 역할)
    public int GetBalance()
    {
        return balance;
    }

    // 출금 기능 (setter 역할)
    public void Withdraw(int amount)
    {
        if (amount > 0 && balance >= amount)
        {
            balance -= amount;
            Console.WriteLine($"{amount}원 출금 완료!");
        }
        else
        {
            Console.WriteLine("출금할 수 없습니다. 잔액 부족 또는 잘못된 금액!");
        }
    }
}

class Program
{
    static void Main()
    {
        BankAccount account = new BankAccount(10000);  // 초기 잔액 10,000원
        Console.WriteLine($"현재 잔액: {account.GetBalance()}");

        account.Withdraw(3000);  // 3000원 출금
        Console.WriteLine($"현재 잔액: {account.GetBalance()}");

        account.Withdraw(8000);  // ❌ 출금 실패 (잔액 부족)
    }
}

🔍 실행 결과

현재 잔액: 10000
3000원 출금 완료!
현재 잔액: 7000
출금할 수 없습니다. 잔액 부족 또는 잘못된 금액!

 

💡 캡슐화 적용 후
✅ private 키워드를 사용하여 외부에서 balance에 직접 접근 불가능
✅ GetBalance(), Withdraw() 메서드를 제공하여 안전한 데이터 조작 가능
✅ 출금 시 잔액을 체크하여 잘못된 값을 방지

 

이제 접근 제한자(public, private, protected)의 차이를 알아볼까요?


🔹 접근 제한자(Access Modifiers) 정리 🔍

C#에서는 변수(필드)와 메서드에 대해 어디서 접근할 수 있는지 제한할 수 있습니다.
대표적인 접근 제한자는 다음과 같습니다.

접근 제한자 설명 사용 가능 범위
public 어디서든 접근 가능 모든 클래스
private 해당 클래스 내에서만 접근 가능 현재 클래스 내부
protected 현재 클래스 & 상속받은 클래스에서만 접근 가능 현재 클래스 + 자식 클래스
internal 같은 프로젝트(어셈블리) 내에서만 접근 가능 동일 프로젝트 내부

각 접근 제한자가 실제로 어떻게 동작하는지 예제와 함께 살펴볼게요!


🔹 public vs private 차이점 👀

📌 public 변수: 외부에서 직접 접근 가능 (⚠ 위험!)

class Person
{
    public string name;  // ✅ 누구나 접근 가능
}

class Program
{
    static void Main()
    {
        Person p = new Person();
        p.name = "지훈";  // 외부에서 직접 수정 가능
        Console.WriteLine($"이름: {p.name}");
    }
}

결과 → 이름: 지훈 (하지만, 외부에서 데이터가 쉽게 변경될 수 있음)


📌 private 변수: 외부에서 직접 접근 불가능 (✅ 안전!)

class Person
{
    private string name;  // 🔒 외부에서 접근 불가능

    public void SetName(string newName)
    {
        name = newName;  // 내부에서만 변경 가능
    }

    public string GetName()
    {
        return name;
    }
}

class Program
{
    static void Main()
    {
        Person p = new Person();
        // p.name = "지훈";  // ❌ 오류 발생 (private 변수는 직접 접근 불가!)
        p.SetName("지훈");  // setter 메서드를 통해 값 설정
        Console.WriteLine($"이름: {p.GetName()}");
    }
}

결과 → 이름: 지훈 (외부에서 name을 직접 변경할 수 없도록 보호됨!)


🔹 protected (상속 관계에서 사용)

💡 protected 키워드는 현재 클래스와 상속받은 자식 클래스에서만 접근 가능합니다.

class Animal
{
    protected string name;  // 자식 클래스에서 접근 가능

    public void SetName(string newName)
    {
        name = newName;
    }
}

class Dog : Animal
{
    public void Bark()
    {
        Console.WriteLine($"{name}가 멍멍 짖습니다!");
    }
}

class Program
{
    static void Main()
    {
        Dog myDog = new Dog();
        myDog.SetName("바둑이");  // 부모 클래스의 public 메서드를 통해 설정
        myDog.Bark();
    }
}

결과 → 바둑이가 멍멍 짖습니다!

💡 protected 덕분에 자식 클래스인 Dog에서 부모 클래스 Animal의 name을 사용할 수 있어요!


🔹 정리

캡슐화(Encapsulation) → 데이터 보호 & 안전한 조작을 위한 객체지향 개념
public → 어디서든 접근 가능 (⚠ 데이터 보호 X)
private → 클래스 내부에서만 접근 가능 (✅ 안전한 데이터 보호)
protected → 현재 클래스 + 상속받은 클래스에서 접근 가능


💡 캡슐화와 접근 제한자는 C# 객체지향 프로그래밍의 필수 개념입니다!
궁금한 점이 있으면 댓글로 질문 주세요! 😊