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 메서드 호출
}
}

이 예제에서, Name과 SayHello() 모두 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 name과 Eat() 메서드를 접근할 수 있지만, 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 internal은 protected와 internal의 조합입니다. 이는 같은 어셈블리 내에서 또는 다른 어셈블리의 파생 클래스에서 접근할 수 있습니다.

// 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