Menu
Coddy logo textTech

접근 제어자

Coddy C# 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 70개 중 31번째.

접근 제어자(Access modifiers)는 클래스 멤버를 누가 보고 사용할 수 있는지를 제어합니다. 이는 OOP의 핵심 원칙 중 하나인 캡슐화(encapsulation)의 기초입니다. 접근을 제한함으로써 데이터를 보호하고 코드 내에 명확한 경계를 만들 수 있습니다.

C#은 네 가지 주요 접근 제한자(access modifiers)를 제공합니다:

public class BankAccount
{
    public string AccountHolder;      // 어디에서나 접근 가능
    private decimal balance;          // 이 클래스 내부에서만 접근 가능
    protected string accountType;     // 이 클래스 및 파생 클래스에서 접근 가능
    internal int branchCode;          // 동일한 어셈블리 내에서 접근 가능
}

public 멤버는 어떤 코드에서든 접근 가능합니다.

private 멤버는 동일한 클래스 내에서만 접근할 수 있습니다. 이는 가장 제한적인 수준이며 클래스 멤버의 기본 설정입니다.

protected는 클래스 자체와 해당 클래스를 상속받는 모든 클래스에서의 접근을 허용합니다.

internal은 동일한 어셈블리(프로젝트) 내의 코드에 대한 액세스를 제한합니다.

한정자가 지정되지 않으면 클래스 멤버는 기본적으로 private으로 설정됩니다:

class Example
{
    int secret;  // 기본적으로 private
}

올바른 접근 수준을 선택하는 것은 필요한 것만 노출하는 것에 관한 것입니다. private으로 시작하고 명확한 이유가 있을 때만 가시성을 높이세요. 이는 다른 코드가 나중에 변경하고 싶을 수 있는 구현 세부 사항에 의존하는 것을 방지합니다.

challenge icon

챌린지

쉬움

액세스 한정자가 필요한 정보만 노출하면서 민감한 데이터를 어떻게 보호하는지 보여주는 보안 사용자 프로필 시스템을 구축해 보겠습니다. 액세스 권한이 있는 대상에 따라 정보의 가시성 수준이 다른 클래스를 만들게 됩니다.

코드는 세 개의 파일로 구성됩니다:

  • UserProfile.cs: 적절한 액세스 수준으로 사용자 정보를 관리하는 Security 네임스페이스 내의 UserProfile 클래스를 생성합니다. 프로필은 다음을 포함해야 합니다:
    • public 속성 Username (string) - 누구나 사용자 이름을 볼 수 있습니다.
    • private 필드 password (string) - 클래스 자체만 이 필드에 액세스할 수 있습니다.
    • protected 필드 email (string) - 클래스와 그 자식 클래스만 이 필드에 액세스할 수 있습니다.
    • internal 필드 userId (int) - 동일한 어셈블리 내에서 액세스할 수 있습니다.
    username, password, email, userId를 매개변수로 받는 생성자를 포함하세요. "User: {Username}"을 반환하는 GetPublicInfo()라는 public 메서드를 추가하세요. 입력값이 private password와 일치하면 true를, 그렇지 않으면 false를 반환하는 ValidatePassword(string input)라는 또 다른 public 메서드를 추가하세요.
  • AdminProfile.cs: UserProfile을 상속받는 Security 네임스페이스 내의 AdminProfile 클래스를 생성합니다. 이 클래스는 파생 클래스에서 protected 멤버에 어떻게 액세스할 수 있는지 보여줍니다. 생성자는 동일한 네 개의 매개변수를 받아 기본(base) 생성자로 전달해야 합니다. "Admin: {Username}, Email: {email}"을 반환하는 GetAdminInfo()라는 public 메서드를 추가하세요. 여기서 protected email 필드에 액세스할 수 있음에 유의하세요!
  • Program.cs: 메인 파일에서 입력값을 사용하여 UserProfileAdminProfile을 생성합니다. 사용 가능한 public 메서드를 호출하고 internal 필드에 직접 액세스하여(동일한 어셈블리에 있으므로) 액세스 수준을 시연하세요. 각 유형의 사용자가 어떤 정보를 드러낼 수 있는지 보여주세요.

다섯 개의 입력을 받게 됩니다:

  • Username
  • Password
  • Email
  • User ID (정수)
  • 검증할 Password attempt

출력은 다음 형식으로 인쇄하세요:

Regular User:
{GetPublicInfo() result}
Internal ID: {userId}
Password valid: {ValidatePassword result}
Admin User:
{GetAdminInfo() result}

예를 들어, 입력값이 alice, secret123, alice@email.com, 1001, secret123인 경우 출력은 다음과 같아야 합니다:

Regular User:
User: alice
Internal ID: 1001
Password valid: True
Admin User:
Admin: alice, Email: alice@email.com

비밀번호가 어떻게 완전히 숨겨져 있는지 확인하세요. 비밀번호는 검증만 가능하며 절대 가져올 수 없습니다. 이메일은 보호되어 있으므로 AdminProfile(파생 클래스)만 노출할 수 있습니다. 내부 userId는 동일한 어셈블리에 있기 때문에 메인 파일에서 액세스할 수 있습니다. 이것이 바로 캡슐화(encapsulation)의 실제 사례입니다!

치트 시트

접근 제한자는 클래스 멤버의 가시성과 접근성을 제어하며, OOP에서 캡슐화의 기초를 형성합니다.

C#은 네 가지 주요 접근 제한자를 제공합니다:

public class BankAccount
{
    public string AccountHolder;      // 어디서나 접근 가능
    private decimal balance;          // 이 클래스 내에서만
    protected string accountType;     // 이 클래스 및 파생 클래스
    internal int branchCode;          // 동일한 어셈블리 내
}

public: 모든 코드에서 접근 가능

private: 동일한 클래스 내에서만 접근 가능 (가장 제한적이며, 클래스 멤버의 기본값)

protected: 클래스 자체와 모든 파생 클래스에서 접근 가능

internal: 동일한 어셈블리(프로젝트) 내에서만 접근 가능

제한자를 지정하지 않으면 클래스 멤버는 기본적으로 private이 됩니다:

class Example
{
    int secret;  // 기본적으로 private
}

권장 사항: private으로 시작하고, 외부 코드가 구현 세부 사항에 의존하는 것을 방지하기 위해 필요한 경우에만 가시성을 높이세요.

직접 해보기

using System;
using Security;

class Program
{
    public static void Main(string[] args)
    {
        // 입력값 읽기
        string username = Console.ReadLine();
        string password = Console.ReadLine();
        string email = Console.ReadLine();
        int userId = Convert.ToInt32(Console.ReadLine());
        string passwordAttempt = Console.ReadLine();

        // TODO: 입력값들을 사용하여 UserProfile 객체 생성

        // TODO: 동일한 입력값들을 사용하여 AdminProfile 객체 생성

        // TODO: "Regular User:" 출력

        // TODO: GetPublicInfo()의 결과 출력

        // TODO: "Internal ID: "와 그 뒤에 userId 필드 출력 (동일 어셈블리이므로 접근 가능)

        // TODO: "Password valid: "와 그 뒤에 ValidatePassword()의 결과 출력

        // TODO: "Admin User:" 출력

        // TODO: GetAdminInfo()의 결과 출력
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨