オーバーロード
Javaでは,引数のパターンが異なる,同じ名称のメソッドを定義することができる.まずは,現在のスタック全体の状態を示すメソッドを見てみよう.メソッド名と引数でメソッドが特定され,現在は,引数がないメソッドである.このように,メソッドを定義するために必要な,メソッド名,引数の数,引数の型を組み合わせたものを「シグネチャ」と呼ぶ.
public class Stack { int volume; private int data[]; static int stackSize = 5;
//標準サイズのためのコンストラクタ Stack() { (略) } //データ追加メソッド boolean push(int number) { (略) } //データ取得メソッド int pop() { (略) } //状態表示メソッド void printStack() { System.out.print("|"); for(int i=0; i < data.length; i++) { System.out.print(data[i]); System.out.print("|"); } System.out.println(""); } }
メソッドの定義が異なっても,シグネチャとしては同じと判断される場合がある.例えば,引数を定義する仮引数名や,戻り値,修飾子が違っても,引数の型としては同じであれば,シグネチャは同じである.これは,そのメソッドを実行するときには違いがないからである.
(1) public int methodName( int hikisu ){(処理内容)} (2) public void methodName( int hikisu ){(処理内容)}//戻り値が異なる (3) private int methodName( int hikisu ){(処理内容)}//修飾子が異なる (4) public int methodName( int number ){(処理内容)}//仮引数名が異なる (5) public static int methodName( int hikisu ){(処理内容)}//staticがついている
例えば,上記のメソッドのいずれを実行するときでも,以下のように呼び出されるので,違いが存在しないことになる.
public static int main(String args[]) { methodName(3); }
メソッドを呼び出すときには,引数の型やパターンの違いから,複数ある同じ名称のメソッドから,どれが実装されるかについて,自動的に判断される.すなわち,シグネチャが異なるメソッドを複数定義することができて,呼び出しの条件に合ったメソッドが自動的に呼び出されることを意味している.
以下で実行している同じ名前のメソッドではあるが,シグネチャが異なるメソッドが呼び出されることになるのは,分かるだろうか.
public static int main(String args[]) { methodName(3); methodName(3.5); methodName(3, 4); }
返り値や,仮引数名に違いはあるかもしれないが,以下のような,シグネチャが異なる3種類のメソッドが定義されていて,それらが区別されて呼び出されていると考えられる.
public static int main(String args[]) { methodName(3); methodName(3.5); methodName(3, 4); } void methodName(int number) { (何らかの処理) } void methodName(double number) { (何らかの処理) } void methodName(int number1, int number2) { (何らかの処理) }
これによって,同じ処理を行うサブルーチンに対して,引数が違っても同じ名称を付けることができるので,統一をとることができる.
以下の例では,printStackメソッドについて,引数があるメソッドと引数がないメソッドの2種類定義している.呼び出すときに,引数がない状態で呼ばれているときには,引数がないメソッドが選択され,引数が与えられているときには,引数があるメソッドが選択される.
class Stack { int volume; int data[]; int defaultSize = 5; //標準サイズのためのコンストラクタ Stack() { data = new int[defaultSize]; System.out.println(data.length + "個分のスタック生成"); } //データ追加メソッド boolean push(int number) { if(volume < data.length) { data[volume] = number; volume++; return true; } else { System.out.println("stack overflow"); return false; } } //データ取得メソッド int pop() { int value; if(volume > 0) { value = data[volume -1]; data[volume -1] = 0; volume--; } else { value = -1; } return value; } //状態表示メソッド void printStack() { System.out.print("|"); for(int i=0; i < data.length; i++) { System.out.print(data[i]); System.out.print("|"); } System.out.println(""); } //個別の状態表示メソッド void printStack(int i) { System.out.print("|"); System.out.print(data[i]+"|"); System.out.println(""); } }
public class Main { public static void main(String[] args) { Stack tower = new Stack(); tower.push(10); tower.push(20); tower.push(30); tower.printStack(); tower.printStack(2); } }
実行例
5個分のスタック生成 |10|20|30|0|0| |30|
演習
スタック
上記のスタッククラスにおいて, 「状態を表示する」メソッドをオーバーロードして,「指定した範囲のスタックの状態を表示する」メソッドを追加して定義せよ. すなわち,「A番目からB番目までのスタック」の状態を表示するために,引数としてA,Bの2つの整数を取るメソッドを追加する.
キュー
キュークラスにおいて,指定したインデックスの場所の値のみを表示するメソッドを定義せよ.また,「start番目からend番目までのキューの状態」を表示する,引数としてstartとendの2件の整数をとるメソッドを追加せよ.メインメソッドにて,引数が異なるメソッドが適切に選択されて実行されていることを確認せよ.