Menu
Coddy logo textTech

연산자 오버로딩

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

연산자 오버로딩을 사용하면 +, - 또는 ==와 같은 연산자가 사용자 정의 클래스에서 어떻게 동작할지 정의할 수 있습니다. point1.Add(point2)와 같은 메서드를 호출하는 대신, 더 자연스러운 point1 + point2를 작성할 수 있습니다.

연산자를 오버로드하려면 operator 키워드를 사용하여 특별한 정적 메서드를 생성합니다:

public class Vector
{
    public int X { get; }
    public int Y { get; }
    
    public Vector(int x, int y)
    {
        X = x;
        Y = y;
    }
    
    public static Vector operator +(Vector a, Vector b)
    {
        return new Vector(a.X + b.X, a.Y + b.Y);
    }
}

이제 벡터를 자연스럽게 더할 수 있습니다:

Vector v1 = new Vector(3, 4);
Vector v2 = new Vector(1, 2);
Vector v3 = v1 + v2;  // X = 4, Y = 6

메서드는 public static이어야 하며, 적어도 하나의 매개변수는 포함하는 유형이어야 합니다. 산술 연산자(+, -, *, /), 비교 연산자(==, !=, <, >), 그리고 단항 연산자(-, !, ++)를 오버로드할 수 있습니다.

비교 연산자는 쌍으로 오버로드되어야 한다는 점에 유의하세요. ==를 정의한다면 !=도 정의해야 합니다.

연산자 오버로딩은 벡터, 복소수 또는 금액과 같은 수학적 타입에 대해 코드를 더 직관적으로 만들 때 사용하세요. 연산의 의미가 즉각적으로 명확하지 않은 경우에는 사용을 피하십시오.

challenge icon

챌린지

쉬움

연산자 오버로딩을 통해 분수 계산을 자연스럽게 처리할 수 있는 Fraction 클래스를 만들어 봅시다. fraction1.Add(fraction2)와 같은 메서드를 호출하는 대신, 직관적인 fraction1 + fraction2와 같은 코드를 작성할 수 있게 됩니다.

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

  • Fraction.cs: Math 네임스페이스 안에 분자와 분모를 나타내는 Fraction 클래스를 생성하세요. 이 클래스는 다음을 포함해야 합니다:
    • 두 개의 읽기 전용 정수 속성: NumeratorDenominator
    • 분자와 분모를 순서대로 받는 생성자
    • 다음 공식을 사용하여 두 분수를 더하는 오버로드된 + 연산자: (a/b) + (c/d) = (a*d + c*b) / (b*d)
    • 두 분수를 곱하는 오버로드된 * 연산자: (a/b) * (c/d) = (a*c) / (b*d)
    • 두 분수가 같은지 확인하여 true를 반환하는 오버로드된 == 연산자 (교차 곱셈으로 비교: a*d == c*b)
    • ==를 오버로드할 때 필수인, ==의 반대 결과를 반환하는 오버로드된 != 연산자
    • 분수를 "{Numerator}/{Denominator}" 형식의 문자열로 반환하는 GetDisplay() 메서드
  • Program.cs: 메인 파일에서 입력값을 사용하여 두 개의 분수를 생성하세요. 두 분수를 더하고, 곱하고, 같은지 확인하여 오버로드된 연산자들을 시연하세요. 연산자들이 자연스럽게 작동하는 것을 보여주기 위해 결과를 출력하세요.

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

  • 첫 번째 분수의 분자 (정수)
  • 첫 번째 분수의 분모 (정수)
  • 두 번째 분수의 분자 (정수)
  • 두 번째 분수의 분모 (정수)

출력은 다음 형식을 따르세요:

Fraction 1: {GetDisplay()}
Fraction 2: {GetDisplay()}
Sum: {GetDisplay()}
Product: {GetDisplay()}
Are equal: {True/False}

예를 들어, 입력값이 1, 2, 2, 4라면 출력은 다음과 같아야 합니다:

Fraction 1: 1/2
Fraction 2: 2/4
Sum: 8/8
Product: 2/8
Are equal: True

1*4 == 2*2이므로 1/22/4가 같다고 인식되는 것을 확인하세요. 합계와 곱은 약분되지 않은 상태로 계산되지만, 이번 챌린지에서는 괜찮습니다. 핵심은 익숙한 연산자를 사용하여 분수를 얼마나 자연스럽게 다룰 수 있는지에 있습니다!

치트 시트

연산자 오버로딩을 사용하면 클래스에서 +, -, *, ==와 같은 연산자에 대해 사용자 정의 동작을 정의할 수 있습니다.

연산자를 오버로딩하려면 operator 키워드를 사용하여 public static 메서드를 생성합니다. 적어도 하나의 매개변수는 해당 형식을 포함해야 합니다:

public class Vector
{
    public int X { get; }
    public int Y { get; }
    
    public Vector(int x, int y)
    {
        X = x;
        Y = y;
    }
    
    public static Vector operator +(Vector a, Vector b)
    {
        return new Vector(a.X + b.X, a.Y + b.Y);
    }
}

사용법:

Vector v1 = new Vector(3, 4);
Vector v2 = new Vector(1, 2);
Vector v3 = v1 + v2;  // X = 4, Y = 6

다음을 오버로딩할 수 있습니다:

  • 산술 연산자: +, -, *, /
  • 비교 연산자: ==, !=, <, > (쌍으로 오버로딩해야 함)
  • 단항 연산자: -, !, ++

==를 오버로딩할 때는 !=도 오버로딩해야 합니다:

public static bool operator ==(Vector a, Vector b)
{
    return a.X == b.X && a.Y == b.Y;
}

public static bool operator !=(Vector a, Vector b)
{
    return !(a == b);
}

직접 해보기

using System;
using Math;

class Program
{
    public static void Main(string[] args)
    {
        // 첫 번째 분수에 대한 입력 읽기
        int num1 = Convert.ToInt32(Console.ReadLine());
        int den1 = Convert.ToInt32(Console.ReadLine());
        
        // 두 번째 분수에 대한 입력 읽기
        int num2 = Convert.ToInt32(Console.ReadLine());
        int den2 = Convert.ToInt32(Console.ReadLine());
        
        // TODO: 입력값을 사용하여 두 개의 Fraction 객체 생성
        
        // TODO: 오버로드된 + 연산자를 사용하여 분수 더하기
        
        // TODO: 오버로드된 * 연산자를 사용하여 분수 곱하기
        
        // TODO: 오버로드된 == 연산자를 사용하여 동일 여부 확인
        
        // TODO: 요구되는 형식으로 출력 인쇄:
        // Fraction 1: {GetDisplay()}
        // Fraction 2: {GetDisplay()}
        // Sum: {GetDisplay()}
        // Product: {GetDisplay()}
        // Are equal: {True/False}
    }
}
quiz icon실력 점검

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

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