C# - 캡슐화: 초보자 가이드

안녕하세요, 미래의 코딩 슈퍼스타! 오늘 우리는 C#의 세계로 흥미로운 여정을 떠나고, 그 중 하나의 기본 개념인 캡슐화를 탐구해보겠습니다. 코드를 한 줄도 작성해본 적이 없더라도 걱정 마세요 - 나는 당신을 모든 단계에서 안내해줄 것입니다. 그麼, 시작해보겠습니다!

C# - Encapsulation

캡슐화는 무엇인가요?

자세한 내용에 들어가기 전에, 캡슐화가 무엇인지 이해해보겠습니다. 마법의 상자가 기말할 만한 일을 할 수 있지만, 내부에서 어떻게 작동하는지 알 필요가 없다면 상상해보세요 - 단지 어떻게 사용하는지 알면 충분합니다. 이것이 캡슐화의 핵심입니다!

C#에서 캡슐화는 데이터(변수)와 그 데이터를 조작하는 메서드를 단일 유닛이나 객체 내에 통합하는 것입니다. 코드 주위에 보호 캡슐을 만드는 것처럼, "캡슐화"라는 이름이 붙었습니다.

이제 C#이 캡슐화를 접근 지시자를 통해 어떻게 구현하는지 탐구해보겠습니다.

C#의 접근 지시자

접근 지시자는 클래스, 메서드, 또는 코드 내의 프로퍼티의 접근성을 정의하는 키워드입니다. 이를 다양한 보안 수준으로 생각할 수 있습니다. C#은 다음 다섯 가지 주요 접근 지시자를 제공합니다:

  1. Public
  2. Private
  3. Protected
  4. Internal
  5. Protected Internal

한 번씩 설명해보겠습니다.

Public 접근 지시자

public 키워드는 "모든 곳에 접근 가능" 티켓과 같습니다. 클래스 멤버를 public으로 선언할 때, 프로그램의 어디서나 접근할 수 있습니다.

public class Person
{
public string Name { get; set; }

public void SayHello()
{
Console.WriteLine($"안녕하세요, 제 이름은 {Name}입니다!");
}
}

class Program
{
static void Main(string[] args)
{
Person person = new Person();
person.Name = "Alice";  // public 프로퍼티 접근
person.SayHello();  // public 메서드 호출
}
}

이 예제에서, NameSayHello() 모두 public이므로 Main 메서드에서 직접 접근할 수 있습니다.

Private 접근 지시자

private은 "직원 전용" 구역과 같습니다. Private 멤버는 같은 클래스 내에서만 접근할 수 있습니다.

public class BankAccount
{
private double balance;

public void Deposit(double amount)
{
if (amount > 0)
{
balance += amount;
}
}

public double GetBalance()
{
return balance;
}
}

class Program
{
static void Main(string[] args)
{
BankAccount account = new BankAccount();
account.Deposit(100);
// account.balance = 1000000;  // 이 작업은 오류를 발생시킵니다!
Console.WriteLine($"잔액: {account.GetBalance()}");
}
}

여기서 balance는 private이므로 BankAccount 클래스 외부에서 직접 접근할 수 없습니다. Deposit()GetBalance()와 같은 public 메서드를 사용하여 상호작용해야 합니다.

Protected 접근 지시자

protected 멤버는 같은 클래스와 파생 클래스 내에서 접근할 수 있습니다. 이는 "가족 전용" 섹션이와 같습니다.

public class Animal
{
protected string name;

public Animal(string name)
{
this.name = name;
}

protected void Eat()
{
Console.WriteLine($"{name}이 먹고 있습니다.");
}
}

public class Dog : Animal
{
public Dog(string name) : base(name) { }

public void Bark()
{
Console.WriteLine($"{name}이 짖고 있습니다!");  // protected 멤버 접근
Eat();  // protected 메서드 호출
}
}

class Program
{
static void Main(string[] args)
{
Dog dog = new Dog("Buddy");
dog.Bark();
// dog.name = "Max";  // 이 작업은 오류를 발생시킵니다!
// dog.Eat();  // 이 작업도 오류를 발생시킵니다!
}
}

이 예제에서 Dog는 부모 클래스 Animal의 protected nameEat() 메서드를 접근할 수 있지만, Main 메서드에서는 직접 접근할 수 없습니다.

Internal 접근 지시자

internal 멤버는 같은 어셈블리 내에서 접근할 수 있습니다(어셈블리는 컴파일된 .dll이나 .exe 파일로 생각할 수 있습니다). 이는 "회사 직원 전용" 구역과 같습니다.

// AssemblyOne.cs에서
internal class InternalClass
{
internal void InternalMethod()
{
Console.WriteLine("이것은 내부 메서드입니다.");
}
}

// Program.cs (같은 어셈블리)
class Program
{
static void Main(string[] args)
{
InternalClass obj = new InternalClass();
obj.InternalMethod();  // 이 작업은 가능합니다!
}
}

// 다른 어셈블리에서는 이 작업이 안 됩니다:
// InternalClass obj = new InternalClass();  // 오류!

Protected Internal 접근 지시자

마지막으로, protected internalprotectedinternal의 조합입니다. 이는 같은 어셈블리 내에서 또는 다른 어셈블리의 파생 클래스에서 접근할 수 있습니다.

// AssemblyOne.cs에서
public class BaseClass
{
protected internal void ProtectedInternalMethod()
{
Console.WriteLine("이것은 protected internal 메서드입니다.");
}
}

// AssemblyTwo.cs에서
public class DerivedClass : BaseClass
{
public void CallProtectedInternalMethod()
{
ProtectedInternalMethod();  // 이 작업은 가능합니다!
}
}

// Program.cs (AssemblyTwo에서)
class Program
{
static void Main(string[] args)
{
DerivedClass obj = new DerivedClass();
obj.CallProtectedInternalMethod();
// obj.ProtectedInternalMethod();  // 이 작업은 안 됩니다!
}
}

접근 지시자 요약

다음 표는 접근 수준을 요약한 것입니다:

접근 지시자 같은 클래스 파생 클래스 (같은 어셈블리) 비파생 클래스 (같은 어셈블리) 파생 클래스 (다른 어셈블리) 비파생 클래스 (다른 어셈블리)
Public
Private 아니요 아니요 아니요 아니요
Protected 아니요 아니요
Internal 아니요 아니요
Protected Internal 아니요

그렇게 해서! C#의 캡슐화에 대한 첫 걸음을 냈습니다. 캡슐화는 코드와 데이터에 대한 접근을 제어하는 것입니다. 이는 보안이 더 높고 유지보수가 가능하며 유연한 프로그램을 작성하는 데 도움이 됩니다.

코딩 여정을 계속하면서 캡슐화가 두 번째 자연스러운 것으로 느껴질 것입니다. 자전거 타는 것을 배우는 것처럼 -처음에는 흔들리지만, 곧 자유자재로 타게 될 것입니다!

계속 연습하고, 호기심을 유지하고, 행복하게 코딩하세요!

Credits: Image by storyset