メソッドオーバーロード
CoddyのC#ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 50/70。
メソッドのオーバーロードを使用すると、同じ名前で異なるパラメータリストを持つ複数のメソッドを定義できます。コンパイラは、渡された引数に基づいて、どのバージョンのメソッドを呼び出すかを決定します。
オーバーロードされた各メソッドは、一意のシグネチャ(パラメータの数が異なるか、パラメータの型が異なるかのいずれか)を持つ必要があります。
public static void Print(string message)
{
Console.WriteLine(message);
}
public static void Print(string message, int times)
{
for (int i = 0; i < times; i++)
Console.WriteLine(message);
}
public static void Print(int number)
{
Console.WriteLine(number);
}// コンパイラが適切なバージョンを選択します
Print("Hello"); // Print(string) を呼び出します
Print("Hi", 3); // Print(string, int) を呼び出します
Print(42); // Print(int) を呼び出しますオーバーロードは、重要な点でオプション引数とは異なります。オプション引数を使用する場合、複数のシナリオを処理する1つのメソッドが存在します。オーバーロードを使用する場合、ケースごとに完全に異なるロジックを含めることができる個別のメソッドが存在します。
戻り値の型だけではメソッドを一意に識別することはできないことに注意してください。戻り値だけが異なる2つのメソッドを持つことはできません。パラメータリストが異なっている必要があります。メソッドのオーバーロードはコンパイル時ポリモーフィズムの一形態であり、どのメソッドを呼び出すかの決定は、コードの実行時ではなく、コンパイル時に行われます。
チャレンジ
簡単メソッドのオーバーロードの力を実証する、多機能な計算機クラスを構築しましょう。単純な2つの数値の演算から、より複雑な計算まで、異なるシナリオを処理する複数のバージョンの計算メソッドを作成します。これらはすべて、同じ直感的なメソッド名を共有します。
コードは2つのファイルに分けて構成します:
Calculator.cs:MathTools名前空間内にCalculatorクラスを作成し、名前は同じですが異なるパラメータを受け取るオーバーロードされたメソッドを作成します:Multiply- 3つのオーバーロードされたバージョンを作成します:- 2つの
intパラメータを受け取り、その積をintとして返すもの - 3つの
intパラメータを受け取り、その積をintとして返すもの - 2つの
doubleパラメータを受け取り、その積をdoubleとして返すもの
- 2つの
Describe- 2つのオーバーロードされたバージョンを作成します:intを受け取り、"Integer: {value}"を返すものdoubleを受け取り、"Double: {value}"を返すもの
Program.cs: メインファイルで、Calculatorのインスタンスを作成し、提供する引数に基づいてコンパイラがどのように自動的に正しいオーバーロードされたメソッドを選択するかを実証します。
4つの入力を受け取ります:
- 1つ目の整数(例:
5) - 2つ目の整数(例:
4) - 3つ目の整数(例:
3) - 小数(例:
2.5)
計算機を使用して、以下の操作を実行し、各結果をそれぞれの行に出力してください:
- 最初の2つの整数を掛け合わせる(2つのintバージョンを使用)
- 3つの整数すべてを掛け合わせる(3つのintバージョンを使用)
- 最初の整数と小数を掛け合わせる(2つのdoubleバージョンを使用)
- 最初の整数を説明する(intバージョンを使用)
- 小数を説明する(doubleバージョンを使用)
例えば、入力が5、4、3、2.5の場合、出力は以下のようになります:
20
60
12.5
Integer: 5
Double: 2.5異なる引数の型や数でMultiplyやDescribeを呼び出しているにもかかわらず、コンパイラが毎回どのバージョンを使用すべきかを正確に判断していることに注目してください。これがコンパイル時ポリモーフィズムの動作です。決定はコードの実行時ではなく、コンパイル時に行われます!
チートシート
メソッドのオーバーロードを使用すると、同じ名前で引数リストが異なる複数のメソッドを定義できます。コンパイラは、渡された引数に基づいて、どのバージョンを呼び出すかを決定します。
各オーバーロードされたメソッドは、一意のシグネチャ(引数の数または引数の型のいずれかが異なる)を持つ必要があります。
public static void Print(string message)
{
Console.WriteLine(message);
}
public static void Print(string message, int times)
{
for (int i = 0; i < times; i++)
Console.WriteLine(message);
}
public static void Print(int number)
{
Console.WriteLine(number);
}
// コンパイラが適切なバージョンを選択します
Print("Hello"); // Print(string) を呼び出します
Print("Hi", 3); // Print(string, int) を呼び出します
Print(42); // Print(int) を呼び出しますメソッドのオーバーロードに関する重要なポイント:
- オーバーロードはオプション引数とは異なります。オーバーロードを使用すると、ケースごとに完全に異なるロジックを含めることができる個別のメソッドを持つことになります。
- 戻り値の型だけではメソッドを一意にすることはできません。引数リストが異なっている必要があります。
- メソッドのオーバーロードはコンパイル時ポリモーフィズムの一形態であり、どのメソッドを呼び出すかの決定は、実行時ではなくコードのコンパイル時に行われます。
自分で試してみよう
using System;
using MathTools;
class Program
{
public static void Main(string[] args)
{
// 入力を読み込む
int firstInt = Convert.ToInt32(Console.ReadLine());
int secondInt = Convert.ToInt32(Console.ReadLine());
int thirdInt = Convert.ToInt32(Console.ReadLine());
double decimalNum = Convert.ToDouble(Console.ReadLine());
// TODO: Calculator インスタンスを作成する
// TODO: 2つの整数を指定して Multiply を呼び出し、結果を表示する
// TODO: 3つの整数を指定して Multiply を呼び出し、結果を表示する
// TODO: 最初の整数と decimalNum を指定して Multiply を呼び出し、結果を表示する
// TODO: 最初の整数を指定して Describe を呼び出し、結果を表示する
// TODO: decimalNum を指定して Describe を呼び出し、結果を表示する
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。