Menu
Coddy logo textTech

캡슐화를 위한 프로퍼티

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

프로퍼티는 C#에서 캡슐화를 구현하기 위한 주요 도구입니다. 필드를 직접 노출하는 대신, 데이터가 액세스되고 수정되는 방식을 제어하는 프로퍼티로 필드를 감쌉니다.

이 패턴은 프라이빗 필드와 접근자(accessor)에 유효성 검사 또는 로직을 포함하는 퍼블릭 속성을 결합합니다:

public class Temperature
{
    private double celsius;
    
    public double Celsius
    {
        get { return celsius; }
        set
        {
            if (value < -273.15)
                celsius = -273.15;  // 절대 영도 최소값
            else
                celsius = value;
        }
    }
}

이제 외부 코드에서 불가능한 온도를 설정할 수 없습니다. 이 속성은 게이트키퍼 역할을 하여 객체가 항상 유효한 상태를 유지하도록 보장합니다. 이것이 바로 캡슐화의 실제 사례입니다. 내부 데이터는 보호되면서도 제어된 인터페이스를 통해 여전히 접근할 수 있습니다.

프로퍼티를 사용하여 값을 계산하거나 사이드 이펙트를 트리거할 수도 있습니다:

public double Fahrenheit
{
    get { return celsius * 9 / 5 + 32; }
    set { celsius = (value - 32) * 5 / 9; }
}

외부에서는 두 개의 프로퍼티를 보지만, 내부적으로는 오직 하나의 필드만 존재합니다. 프로퍼티를 사용하면 클래스를 사용하는 코드를 망가뜨리지 않고도 구현 세부 사항을 변경할 수 있습니다. 이는 적절한 캡슐화(encapsulation)의 핵심적인 이점입니다.

challenge icon

챌린지

쉬움

데이터 무결성을 보호하기 위해 속성(properties)을 사용하는 제품 인벤토리 시스템을 구축해 보겠습니다. 가격이 절대 음수가 될 수 없고 수량이 항상 유효한 범위 내로 유지되는 클래스를 만들게 됩니다. 이는 속성이 데이터의 게이트키퍼(gatekeeper) 역할을 하는 방식을 보여줍니다.

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

  • Product.cs: Inventory 네임스페이스 안에 속성을 통한 유효성 검사로 제품 정보를 관리하는 Product 클래스를 만듭니다. 제품에는 다음이 필요합니다:
    • 프라이빗 필드 price (decimal)와 퍼블릭 Price 속성: 가격이 0 미만으로 내려가지 않도록 보장해야 합니다. 누군가 음수 가격을 설정하려고 하면 대신 0으로 저장되어야 합니다.
    • 프라이빗 필드 quantity (int)와 퍼블릭 Quantity 속성: 값을 0에서 1000 사이로 유지합니다. 0 미만의 값은 0이 되고, 1000을 초과하는 값은 1000이 됩니다.
    • 퍼블릭 자동 구현 속성 Name (string)
    • Price * Quantity를 반환하는 계산된 읽기 전용 속성 TotalValue
    이름, 가격, 수량(이 순서대로)을 받아 유효성 검사가 적용되도록 속성을 통해 모든 값을 설정하는 생성자를 포함하세요.
  • Program.cs: 메인 파일에서 입력 값을 사용하여 Product를 생성합니다. 그런 다음 유효하지 않을 수 있는 추가 입력 값을 사용하여 가격과 수량을 수정해 봅니다. 생성 후와 각 수정 후의 제품 상태를 출력하여 속성이 데이터를 어떻게 보호하는지 확인하세요.

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

  • 제품 이름
  • 초기 가격 (decimal)
  • 초기 수량 (integer)
  • 새로 설정할 가격 (decimal, 음수일 수 있음)
  • 새로 설정할 수량 (integer, 범위를 벗어날 수 있음)

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

After creation:
{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
After modifications:
{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}

예를 들어, 입력값이 Laptop, 999.99, 50, -100, 1500인 경우 출력은 다음과 같아야 합니다:

After creation:
Laptop: Price=999.99, Qty=50, Total=49999.50
After modifications:
Laptop: Price=0, Qty=1000, Total=0

음수 가격이 0이 되고 1500이라는 수량이 1000으로 제한된 방식에 주목하세요. 속성이 객체를 유효하지 않은 상태로부터 보호하고 있습니다. 이것이 바로 캡슐화(encapsulation)의 원리입니다!

치트 시트

프로퍼티는 getset 접근자를 통한 제어된 액세스로 프라이빗 필드를 래핑하여, 유효성 검사 및 캡슐화를 가능하게 합니다:

public class Temperature
{
    private double celsius;
    
    public double Celsius
    {
        get { return celsius; }
        set
        {
            if (value < -273.15)
                celsius = -273.15;
            else
                celsius = value;
        }
    }
}

프로퍼티는 내부 필드를 기반으로 값을 계산할 수 있습니다:

public double Fahrenheit
{
    get { return celsius * 9 / 5 + 32; }
    set { celsius = (value - 32) * 5 / 9; }
}

읽기 전용 프로퍼티는 set 접근자를 생략하여, 계산되거나 저장된 값의 검색만 허용합니다.

직접 해보기

using System;
using Inventory;

class Program
{
    public static void Main(string[] args)
    {
        // 입력 읽기
        string name = Console.ReadLine();
        decimal initialPrice = Convert.ToDecimal(Console.ReadLine());
        int initialQuantity = Convert.ToInt32(Console.ReadLine());
        decimal newPrice = Convert.ToDecimal(Console.ReadLine());
        int newQuantity = Convert.ToInt32(Console.ReadLine());

        // TODO: 초기값을 사용하여 Product 생성
        
        // TODO: 생성 후 제품 상태 출력
        Console.WriteLine("After creation:");
        // 출력 형식: {Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
        
        // TODO: 새로운 값으로 가격과 수량 수정
        
        // TODO: 수정 후 제품 상태 출력
        Console.WriteLine("After modifications:");
        // 출력 형식: {Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
    }
}
quiz icon실력 점검

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

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