演算子のオーバーロード
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 を避けてください。
チャレンジ
簡単Fraction class を作成して、operator overloading によって分数を自然に扱えるようにしましょう。fraction1.Add(fraction2) のような method を呼び出す代わりに、直感的な fraction1 + fraction2 と書けるようになります。
コードを2つのファイルに分けて整理します。
Fraction.cs:Mathnamespace に、numerator と denominator を持つ分数を表すFractionclass を Create します。Fraction には次の要素を持たせます。- 2つの read-only integer properties:
NumeratorとDenominator - 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
- 2つの read-only integer properties:
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 が 1、2、2、4 の場合、output は次のようになります。
Fraction 1: 1/2
Fraction 2: 2/4
Sum: 8/8
Product: 2/8
Are equal: True1/2 と 2/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}
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: C#オンラインコンパイラ