Menu
Coddy logo textTech

演算子のオーバーロード

CoddyのC#ジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 36/70。

演算子のオーバーロードを使うと、カスタムクラスで +-== のような演算子がどのように動作するかを定義できます。point1.Add(point2) のような method を呼び出す代わりに、より自然な point1 + point2 と記述できます。

演算子をoverloadするには、operatorキーワードを使用して特別な静的methodを作成します。

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でなければならず、少なくとも1つのパラメーターはそれを含む型でなければなりません。算術演算子(+-*/)、比較演算子(==!=<>)、および単項演算子(-!++)をオーバーロードできます。

比較演算子はペアでオーバーロードする必要があることに注意してください。==を定義する場合は、!=も定義する必要があります。

コードをより直感的にできる場合、特にベクトル、複素数、金額などの数学的な型では、operator overloading を使用してください。操作の意味がすぐに明らかにならない場合は、operator overloading を避けてください。

challenge icon

チャレンジ

簡単

Fraction class を作成して、operator overloading によって分数を自然に扱えるようにしましょう。fraction1.Add(fraction2) のような method を呼び出す代わりに、直感的な fraction1 + fraction2 と書けるようになります。

コードを2つのファイルに分けて整理します。

  • Fraction.cs: Math namespace に、numerator と denominator を持つ分数を表す Fraction class を Create します。Fraction には次の要素を持たせます。
    • 2つの read-only integer properties: NumeratorDenominator
    • numerator と denominator を(この順番で)accepts する constructor
    • 次の Formula を使って2つの分数を加算する overloaded + operator: (a/b) + (c/d) = (a*d + c*b) / (b*d)
    • 2つの分数を multiply する overloaded * operator: (a/b) * (c/d) = (a*c) / (b*d)
    • 2つの分数が equal である場合に true を返す overloaded == operator(比較には cross-multiply を使用: a*d == c*b
    • == を overload すると required になる overloaded != operator。== の反対を返します
    • 分数を "{Numerator}/{Denominator}" の format の string として返す GetDisplay() method
  • Program.cs: main file で、input values を使って2つの分数を Create します。それらを add、multiply し、equal かどうかを check して、overloaded operators を実演します。operators が自然に動作することを示すため、結果を Print します。

4つの input を受け取ります。

  • First fraction's numerator(integer)
  • First fraction's denominator(integer)
  • Second fraction's numerator(integer)
  • Second fraction's denominator(integer)

次の format で output を Print します。

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

たとえば input が 1224 の場合、output は次のようになります。

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

1/22/4 が、1*4 == 2*2 であるため equal と認識されることに注目してください。Sum と product は simplification なしで計算されますが、この challenge では問題ありません。familiar な operators を使って、Fraction をこれほど自然に扱えるようになることが、この方法の魅力です。

自分で試してみよう

using System;
using Math;

class Program
{
    public static void Main(string[] args)
    {
        // 最初の分数の入力を読み取る
        int num1 = Convert.ToInt32(Console.ReadLine());
        int den1 = Convert.ToInt32(Console.ReadLine());
        
        // 2番目の分数の入力を読み取る
        int num2 = Convert.ToInt32(Console.ReadLine());
        int den2 = Convert.ToInt32(Console.ReadLine());
        
        // TODO: 入力値を使用して2つの Fraction オブジェクトを作成する
        
        // TODO: オーバーロードされた + 演算子を使用して分数を加算する
        
        // TODO: オーバーロードされた * 演算子を使用して分数を乗算する
        
        // TODO: オーバーロードされた == 演算子を使用して等価性を確認する
        
        // TODO: 必要な形式で出力を印刷する:
        // 分数 1: {GetDisplay()}
        // 分数 2: {GetDisplay()}
        // 合計: {GetDisplay()}
        // 積: {GetDisplay()}
        // Are equal: {True/False}
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: C#オンラインコンパイラ