オーバーロード
オーバーロードについて学んだことのメモ書きです。
オーバーロードとは
「同名だが、引数の型や数が異なる」メソッド 又は コンストラクタ を 複数記述すること です。
呼び出す場合は、「引数の型 や 引数の数 が 同等」 な メソッド
又は コンストラクタ が呼ばれ処理を行います。
オーバーロードのメリット
攻撃を行う「 attack 」、足し算を行う「 Plus 」など、メソッドの名前をわかりやすく、短く命名したかったり、適切な メソッド名が思い浮かばくてもともとあるメソッド名を使いまわしたい場面がでてくるとおもいます。
ですが、「原則的に同名のメソッドは定義することが出来ません。」
例えば、「 計算 」を行う名前の同じメソッドが存在すると、コンピューターが 「どの計算メソッドだよ!」ってわからなくなってしまうためです。
ただし、引数の型や個数が違う場合は同名のメソッドがあっても、引数が違えばどれを呼べばいいのかコンピュータが判断できるようになり、同名のメソッドを定義することができます。
「引数 によって最終的な処理結果を変更」したり、「処理の結果にバリエーションをもたせたりすることが可能」ですごく便利。
オーバーロードの使い方
メソッドをオーバーロードする例です。
「 plus 」をいう同名のメソッドを複数記述していますが、与えられる引数の数によって返す値がことなります!
public class Sum {
public int plus(int a) {
return a + 1;
}
public int plus(int a, int b) {
return a + b;
}
public int plus(int a, int b, int c) {
return a + b + c;
}
}
コンストラクタをオーバーロードする例
public class Sum {
private int a;
private int b;
private int c;
public Sum(int a) {
this.constructor(a, 0, 0);
}
public Sum(int a, int b) {
this.constructor(a, b, 0);
}
public Sum(int a, int b, int c) {
this.constructor(a, b, c);
}
private void constructor(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
System.out.println("abc = " + (this.a + this.b + this.c));
}
}
デフォルトコンストラクタ
通常、コンストラクタは、そのクラス内に何も記述しなければ デフォルトコンストラクタ が用意されます。
(※コード上にはないが、実処理( new クラス名 )のタイミングで空のコンストラクタ( public Sum() {} )を呼び出している状態となります。
オーバーロードを生かしたコンストラクタ
冗長な記述を減らすことで、可読性が高い初期化処理の実現に役立ちます。
ですが、以下の場合はコンパイル時点で エラー「再帰的コンストラクター」 を吐いてしまい、処理を実現することができません。
// A
public Sum(int a) {
this(a, 0, 0); // ←こちらはOK
}
// B
public Sum(int a, int b) {
this(a, b, 0); // ←こちらもOK
}
// C
public Sum(int a, int b, int c) {
this(a, b, c); // ←こちらを記述したタイミングでエラー
}
なぜエラーが起きるかというと、
「C自身が、自分のコンストラクタを呼び出すことによる処理の終結が無いから」です!
- A と B → C を呼び出す
- C → Cを呼び出す
結局Cにいきつくため、Cを読み込んだのと同じ状態になり、コンストラクタの処理が終わらない状態になります。
そのため、3つのコンストラクタ内で共通で使用できるメソッド (今回の場合:constructor() )を用意して一つの口で初期化できるようにしています。
例題
フルネームを出力するプログラムを組んでみました。
【fulNameMain.java】
package practice_overlord;
public class fullNameMain {
public static void main(String[] args) {
FullName fullName = new FullName();
String printfullName = fullName.anchorName("ゴール", "D", "ロジャー");
System.out.println(printfullName);
}
}
【FullName.java】
package practice_overlord;
public class FullName {
public String anchorName(String firstName) {
return firstName + 1;
}
public String anchorName(String firstName, String lastName) {
return firstName + " " + lastName;
}
public String anchorName(String firstName, String middleName, String lastName) {
return firstName + " " + middleName + " " + lastName;
}
}