
Java超|メソッドのオーバーロード
同じ技名でも、渡す内容で動きが変わる。オーバーロードを使えば、メソッド名を増やしすぎず、自然で使いやすいクラスを作れます。
クラスを使ってプログラムを書いていると、似たような処理をいくつか用意したくなることがあります。
たとえば、サイヤ人戦士の状態を設定するときに、次のような場面が考えられます。
戦闘力だけを変更したい。
気の量だけを変更したい。
戦闘力と気の量をまとめて変更したい。
このような処理は、どれも「戦士の状態を設定する」という同じ目的を持っています。
しかし、それぞれにまったく別のメソッド名をつけると、使う側は覚える名前が増えてしまいます。
たとえば、戦闘力用、気の量用、両方用で別々の名前をつけると、どれを使えばよいのか少し迷いやすくなります。
そこでJavaには、同じ名前のメソッドを、引数の違いで使い分けるしくみがあります。
これが、メソッドのオーバーロードです。
ドラゴンボールの世界観でたとえると、同じ「戦士状態を整える技」でも、渡す内容によって発動する形が変わるイメージです。
戦闘力だけ渡せば、戦闘力を整える。
気の量だけ渡せば、気の量を整える。
戦闘力と気の量を両方渡せば、両方をまとめて整える。
このように、同じ技名を使いながら、状況に合わせて処理を使い分けられるのがオーバーロードです。
オーバーロードとは
オーバーロードとは、同じクラスの中で、同じ名前のメソッドを複数定義することです。
ただし、完全に同じ形のメソッドを複数書けるわけではありません。
大切な条件があります。
引数の型が違う。
または、引数の個数が違う。
このどちらかの違いが必要です。
たとえば、次の3つはオーバーロードとして成り立ちます。
setSaiyan(int p)
setSaiyan(double e)
setSaiyan(int p, double e)どれも setSaiyan という同じ名前です。
しかし、引数が違います。
| メソッド | 引数 | 意味 |
|---|---|---|
| setSaiyan(int p) | int 1個 | 戦闘力だけを設定する |
| setSaiyan(double e) | double 1個 | 気の量だけを設定する |
| setSaiyan(int p, double e) | int と double の2個 | 戦闘力と気の量をまとめて設定する |
Javaは、呼び出すときに渡された引数を見て、どのメソッドを使うべきか判断します。
つまり、メソッド名だけで判断しているのではなく、引数の型や個数も見て判断しているのです。
ドラゴンボールでたとえると、同じ技名を状況で使い分ける
ドラゴンボールでたとえると、オーバーロードは「同じ技名だけれど、込める情報によって効果が変わる技」です。
たとえば、戦士の状態を整える setSaiyan という技があるとします。
しかし、戦闘前の状況によって、整えたい内容は変わります。
| 状況 | 渡す情報 | 実行したい処理 |
|---|---|---|
| 戦闘力だけ整えたい | 10000 | 戦闘力を10000にする |
| 気の量だけ整えたい | 20.5 | 気の量を20.5にする |
| 両方まとめて整えたい | 10000, 20.5 | 戦闘力と気の量をまとめて設定する |
この3つは、細かい処理は違います。
しかし、目的としてはどれも「戦士の状態を設定する」ことです。
だから、全部を setSaiyan という同じ名前でまとめると、使う側にとって自然です。
ドラゴンボールで言えば、同じ流派の技を、型や状況に応じて使い分けるような感覚です。
同じ名前でも、引数が違えば別のメソッドとして扱える
Javaでは、メソッドを見分けるときに、メソッド名だけでなく引数も見ます。
そのため、同じ名前でも、引数の型や個数が違えば、別のメソッドとして定義できます。
たとえば、次の3つはすべて別のメソッドとして扱われます。
public void setSaiyan(int p)
public void setSaiyan(double e)
public void setSaiyan(int p, double e)見た目は似ていますが、引数の形が違います。
| 呼び出し方 | Javaが選ぶメソッド |
|---|---|
| goku.setSaiyan(10000) | setSaiyan(int p) |
| goku.setSaiyan(20.5) | setSaiyan(double e) |
| goku.setSaiyan(10000, 20.5) | setSaiyan(int p, double e) |
このように、Javaは渡された値の型や個数をもとに、呼び出すメソッドを選びます。
使う側は、状態を設定したいときは setSaiyan を使う、と覚えればよくなります。
そのうえで、渡す値によって適切な処理が選ばれます。
図:同じ名前でも引数で選ばれる

この図が示していること
この図では、setSaiyan という同じ名前のメソッドが、引数の違いによって3種類に分かれている様子を表しています。
int 1個なら戦闘力だけを設定します。
double 1個なら気の量だけを設定します。
int と double の2個なら、戦闘力と気の量をまとめて設定します。
ここから分かるのは、Javaではメソッド名だけでなく、引数の型や個数を見て、どのメソッドを呼ぶか判断しているということです。
オーバーロードの動きを確認する
実際のプログラムで、オーバーロードの動きを見ていきましょう。
ファイル名:Sample3.java
class Saiyan
{
private int power;
private double kiEnergy;
public void setSaiyan(int p)
{
power = p;
System.out.println("戦闘力を" + power + "にしました。");
}
public void setSaiyan(double e)
{
kiEnergy = e;
System.out.println("気の量を" + kiEnergy + "にしました。");
}
public void setSaiyan(int p, double e)
{
power = p;
kiEnergy = e;
System.out.println("戦闘力を" + power + "に気の量を" + kiEnergy + "にしました。");
}
public void show()
{
System.out.println("戦闘力は" + power + "です。");
System.out.println("気の量は" + kiEnergy + "です。");
}
}
class Sample3
{
public static void main(String[] args)
{
Saiyan goku = new Saiyan();
goku.setSaiyan(10000, 20.5);
goku.show();
System.out.println("戦闘力だけ変更します。");
goku.setSaiyan(12000);
goku.show();
System.out.println("気の量だけ変更します。");
goku.setSaiyan(30.5);
goku.show();
}
}このプログラムでは、Saiyan クラスの中に setSaiyan という同じ名前のメソッドが3つあります。
public void setSaiyan(int p)
public void setSaiyan(double e)
public void setSaiyan(int p, double e)これがオーバーロードです。
3つとも同じ名前ですが、引数の型や個数が違います。
| メソッド | 引数の違い | 処理内容 |
|---|---|---|
| setSaiyan(int p) | int 1個 | 戦闘力だけを設定 |
| setSaiyan(double e) | double 1個 | 気の量だけを設定 |
| setSaiyan(int p, double e) | int と double の2個 | 戦闘力と気の量を設定 |
最初の呼び出しでは、引数が2個のメソッドが使われる
main メソッドの最初では、次のように呼び出しています。
goku.setSaiyan(10000, 20.5);ここでは、実引数が2つあります。
10000 は int 型です。
20.5 は double 型です。
そのため、Javaは次のメソッドを選びます。
public void setSaiyan(int p, double e)このメソッドでは、戦闘力と気の量の両方を設定します。
power = p;
kiEnergy = e;つまり、次のように値が入ります。
| フィールド | 入る値 |
|---|---|
| power | 10000 |
| kiEnergy | 20.5 |
そのあとで show() を呼び出します。
goku.show();すると、戦闘力と気の量が表示されます。
戦闘力を10000に気の量を20.5にしました。
戦闘力は10000です。
気の量は20.5です。ドラゴンボールでたとえると、戦闘前に「戦闘力10000、気の量20.5」とまとめて整えている場面です。
次は int 1個なので、戦闘力だけ変わる
次に、次の処理があります。
System.out.println("戦闘力だけ変更します。");
goku.setSaiyan(12000);
goku.show();ここで渡しているのは 12000 だけです。
12000 は int 型なので、Javaは次のメソッドを選びます。
public void setSaiyan(int p)このメソッドでは、power だけを変更します。
power = p;そのため、戦闘力は 12000 に変わります。
しかし、kiEnergy はこのメソッドでは変更していません。
そのため、気の量は前の 20.5 のままです。
| 項目 | 呼び出し前 | 呼び出し後 |
|---|---|---|
| power | 10000 | 12000 |
| kiEnergy | 20.5 | 20.5 |
実行結果は次のようになります。
戦闘力だけ変更します。
戦闘力を12000にしました。
戦闘力は12000です。
気の量は20.5です。同じ setSaiyan という名前を使っているのに、int 1個を渡したことで、戦闘力だけを変更する処理が選ばれています。
ドラゴンボールでたとえると、気の量はそのままにして、戦闘力だけを高めている状態です。
次は double 1個なので、気の量だけ変わる
さらに次の処理を見ます。
System.out.println("気の量だけ変更します。");
goku.setSaiyan(30.5);
goku.show();ここで渡しているのは 30.5 だけです。
30.5 は double 型なので、Javaは次のメソッドを選びます。
public void setSaiyan(double e)このメソッドでは、kiEnergy だけを変更します。
kiEnergy = e;そのため、気の量は 30.5 に変わります。
一方で、power はこのメソッドでは変更していません。
そのため、戦闘力は 12000 のままです。
| 項目 | 呼び出し前 | 呼び出し後 |
|---|---|---|
| power | 12000 | 12000 |
| kiEnergy | 20.5 | 30.5 |
実行結果は、次のようになります。
気の量だけ変更します。
気の量を30.5にしました。
戦闘力は12000です。
気の量は30.5です。ここでも、メソッド名は同じ setSaiyan です。
しかし、渡した引数が double 1個なので、気の量だけを変更するメソッドが選ばれました。
ドラゴンボールでたとえると、戦闘力はそのままにして、気の量だけを高め直したようなイメージです。
実行結果で全体の流れを見る
Sample3.java の実行結果をまとめると、次のようになります。
戦闘力を10000に気の量を20.5にしました。
戦闘力は10000です。
気の量は20.5です。
戦闘力だけ変更します。
戦闘力を12000にしました。
戦闘力は12000です。
気の量は20.5です。
気の量だけ変更します。
気の量を30.5にしました。
戦闘力は12000です。
気の量は30.5です。この結果から、同じ setSaiyan という名前でも、渡す引数によって違う処理が実行されていることが分かります。
| 呼び出し | 選ばれる処理 | 変わる値 |
|---|---|---|
| setSaiyan(10000, 20.5) | int, double の2個を受け取るメソッド | 戦闘力と気の量 |
| setSaiyan(12000) | int 1個を受け取るメソッド | 戦闘力 |
| setSaiyan(30.5) | double 1個を受け取るメソッド | 気の量 |
これが、オーバーロードの基本的な動きです。
1つのメソッド名を覚えるだけでよい
オーバーロードの便利さは、使う側から見るとよく分かります。
もしオーバーロードを使わないなら、次のように別々の名前を考えるかもしれません。
| 目的 | 別名で分ける場合の例 |
|---|---|
| 戦闘力を設定する | setPower |
| 気の量を設定する | setKiEnergy |
| 戦闘力と気の量を設定する | setPowerAndKiEnergy |
もちろん、このように名前を分けてもプログラムは作れます。
ただ、似た目的の処理なのにメソッド名が増えると、使う側は覚えることが増えます。
一方、オーバーロードを使えば、状態を設定したいときは setSaiyan を使う、と考えられます。
| 方式 | 覚える名前 | 使い分け |
|---|---|---|
| 別名で分ける | setPower、setKiEnergy、setPowerAndKiEnergy | 名前で使い分ける |
| オーバーロード | setSaiyan | 引数で使い分ける |
ドラゴンボールでたとえると、似た技に全部バラバラの名前をつけるより、同じ流派の技としてまとめ、型の違いで使い分けるほうが覚えやすいということです。
似た役割の処理を1つの名前にまとめられる
オーバーロードの本質は、同じ名前を使えることだけではありません。
大切なのは、似た役割を持つ処理を、1つの名前にまとめられることです。
Sample3.java の setSaiyan は、どれも「戦士の状態を設定する」という共通の目的を持っています。
| メソッド | 細かい役割 | 共通する目的 |
|---|---|---|
| setSaiyan(int p) | 戦闘力だけ設定 | 戦士の状態を整える |
| setSaiyan(double e) | 気の量だけ設定 | 戦士の状態を整える |
| setSaiyan(int p, double e) | 両方設定 | 戦士の状態を整える |
このように、同じ目的を持つ処理を同じ名前にまとめると、クラス全体が読みやすくなります。
「設定する処理は setSaiyan にまとまっている」と分かるからです。
これは、クラスを使う人にも、クラスを読む人にもやさしい設計です。
図:3つの setSaiyan が状態を変える流れ

この図が示していること
この図では、3つの setSaiyan が、goku オブジェクトの状態をどのように変えるかを示しています。
setSaiyan(10000, 20.5) では、power と kiEnergy の両方を設定します。
setSaiyan(12000) では、power だけを変更し、kiEnergy は前の値のままです。
setSaiyan(30.5) では、kiEnergy だけを変更し、power は前の値のままです。
ここから分かるのは、同じメソッド名でも、引数の型や個数によって実行される処理が変わるということです。
多態性という考え方にもつながる
オーバーロードは、同じ名前が状況によって別の働きを持つという点で、多態性という考え方にもつながります。
ここでは難しく広げすぎなくて大丈夫です。
まずは、次の感覚を持てれば十分です。
同じ setSaiyan という名前でも、渡す引数によって選ばれる処理が変わる。
ドラゴンボールでたとえると、同じ技名でも、込める力や型の違いによって発動内容が変わるようなものです。
この柔軟さによって、メソッド名を整理しながら、いくつもの使い方を用意できます。
オーバーロードには大事なルールがある
オーバーロードには、必ず押さえておきたいルールがあります。
同じ名前のメソッドを複数定義するには、引数の型または個数が異なっている必要があります。
| 違い | オーバーロードできるか | 例 |
|---|---|---|
| 引数の型が違う | できる | int と double |
| 引数の個数が違う | できる | 1個と2個 |
| 引数の順番が違う | できる場合がある | int, double と double, int |
| 戻り値だけが違う | できない | int と void の違いだけ |
Sample3.java の setSaiyan は、この条件を満たしています。
| メソッド | 違い |
|---|---|
| setSaiyan(int p) | int 1個 |
| setSaiyan(double e) | double 1個 |
| setSaiyan(int p, double e) | int と double の2個 |
だからJavaは、呼び出し時にどれを選べばよいか判断できます。
戻り値だけが違ってもオーバーロードにはならない
ここはとても重要です。
オーバーロードでは、戻り値の違いだけではメソッドを区別できません。
たとえば、次の2つがあったとします。
int setSaiyan(int p)
void setSaiyan(int p)この2つは、メソッド名が同じです。
そして、引数も int 1個で同じです。
違うのは戻り値だけです。
しかし、これではオーバーロードにはなりません。
なぜなら、呼び出し側が次のように書いたとき、Javaがどちらを呼べばよいか判断できないからです。
goku.setSaiyan(12000);この呼び出しだけを見ると、引数は int 1個です。
戻り値を使うかどうかだけでは、どちらのメソッドを選ぶべきか安全に判断できません。
そのため、Javaでは戻り値だけが違うメソッドをオーバーロードとして扱いません。
| 比較する違い | オーバーロードできるか |
|---|---|
| setSaiyan(int p) と setSaiyan(double e) | できる |
| setSaiyan(int p) と setSaiyan(int p, double e) | できる |
| int setSaiyan(int p) と void setSaiyan(int p) | できない |
オーバーロードでは、戻り値ではなく、引数を見る。
ここをしっかり押さえておくと、設計で迷いにくくなります。
図:オーバーロードできる違い、できない違い

この図が示していること
この図では、オーバーロードとして成り立つ違いと、成り立たない違いを比較しています。
引数の型が違う場合や、引数の個数が違う場合は、Javaがどのメソッドを呼ぶべきか判断できます。
そのため、オーバーロードとして定義できます。
一方で、戻り値だけが違う場合は、呼び出し時の形が同じになってしまいます。
そのため、Javaはどちらを呼べばよいか判断できず、オーバーロードとして扱えません。
ここから分かるのは、オーバーロードでは「戻り値」ではなく「引数の型や個数」が重要だということです。
オーバーロードを使うときの見方
オーバーロードを使うときは、次のように考えると整理しやすいです。
| 見るポイント | 意識すること |
|---|---|
| メソッド名 | 同じ目的の処理を同じ名前にまとめられるか |
| 引数の型 | int、double、String などで区別できるか |
| 引数の個数 | 1個、2個などで区別できるか |
| 使う側の分かりやすさ | メソッド名が増えすぎていないか |
| 戻り値 | 戻り値だけで区別しようとしていないか |
オーバーロードは、ただ同じ名前を使うためのテクニックではありません。
似た目的の処理を整理し、使いやすいクラスにするための考え方です。
ドラゴンボールでたとえると、同じ流派の技を、型や込める力によって使い分けるようなものです。
技名の軸がそろっているので、使う側は覚えやすくなります。
一方で、引数の違いによって、必要な動きだけを選べます。
いちばん大事な感覚
メソッドのオーバーロードで大切なのは、次の感覚です。
| ポイント | 内容 |
|---|---|
| オーバーロード | 同じ名前のメソッドを複数定義すること |
| 条件 | 引数の型または個数が違うこと |
| 呼び分け | Javaが渡された引数を見て選ぶ |
| 便利な点 | 似た目的の処理を同じ名前にまとめられる |
| 注意点 | 戻り値だけが違ってもオーバーロードできない |
ドラゴンボールでたとえると、setSaiyan は「戦士の状態を整える技」です。
戦闘力だけ整える型。
気の量だけ整える型。
戦闘力と気の量をまとめて整える型。
このように、同じ技名を使いながら、渡す情報によって働きを変えられるのがオーバーロードです。
この感覚がつかめると、メソッド名をむやみに増やさず、自然で分かりやすいクラス設計ができるようになります。
