オーバーロード(多重定義) おーばーろーど
簡単に言うとこんな感じ!
「同じ名前のメソッドを引数の種類・数によって使い分けられる仕組み」だよ!たとえば「add(1, 2)」も「add(1.5, 2.5)」も同じ名前の add で呼べるのに、中身の処理を変えられるってこと!レストランで「ランチ(単品)」「ランチ(セット)」みたいに、名前が同じでもオプション次第で内容が変わるイメージだね。
オーバーロードとは
オーバーロード(overload)とは、同一クラス内に同じ名前のメソッド(関数)を複数定義できる仕組みのことです。ただし、それぞれのメソッドは引数の型・数・順序のいずれかが異なっていなければならないというルールがあります。プログラミング言語の世界では「多重定義」とも呼ばれます。
たとえばJavaで print(String text) と print(int number) を同じクラスに書いても、コンパイラは引数の型を見て「どちらの print を呼ぶべきか」を判断してくれます。呼び出し側は同じ名前を使えるので、コードがシンプルでわかりやすくなります。
オーバーロードはコンパイル時(静的)に呼び出すメソッドが決まるのが大きな特徴で、これを「静的ポリモーフィズム」と呼びます。実行時に動的に振る舞いを変える「オーバーライド」とは根本的に仕組みが異なります。
オーバーロードの構造と仕組み
オーバーロードが成立するためには、メソッドのシグネチャ(signature)—— すなわち「メソッド名+引数リスト」—— が異なる必要があります。
| 条件 | オーバーロード成立? | 備考 |
|---|---|---|
| 引数の型が異なる | ✅ | add(int, int) vs add(double, double) |
| 引数の数が異なる | ✅ | add(int) vs add(int, int) |
| 引数の順序が異なる | ✅ | add(int, double) vs add(double, int) |
| 戻り値の型のみが異なる | ❌ | シグネチャは同じとみなされる |
| 引数名のみが異なる | ❌ | 型・数・順序が同じなのでNG |
Java での記述例
class Calculator {
// ① 整数の足し算
int add(int a, int b) {
return a + b;
}
// ② 小数の足し算(引数の型が違う → オーバーロード成立)
double add(double a, double b) {
return a + b;
}
// ③ 3つの整数の足し算(引数の数が違う → オーバーロード成立)
int add(int a, int b, int c) {
return a + b + c;
}
}
覚え方:「荷物の種類でレーンが変わる宅配便」
同じ「配送」という作業(メソッド名)でも、荷物が小型・大型・冷蔵かによって処理するレーンが変わるイメージ。呼ぶ側は「配送してください」と言うだけ。中身の仕分けはコンパイラ(配送センター)がやってくれる!
歴史と背景
- 1960年代: ALGOL 68 などで同名関数の多重定義の概念が現れ始める
- 1980年代: C++ の設計において Ada や Simula の影響を受けながらオーバーロードが正式に言語仕様に組み込まれる
- 1990年代: Java(1995年〜)がC++のオーバーロードを引き継ぎ、エンタープライズ開発で広く普及。「同じ名前・異なる引数」というルールが開発者の常識になる
- 2000年代以降: C#、Kotlin、Swift など後発の言語も同様の仕組みを採用。Python は動的型付け言語のため従来の意味でのオーバーロードはなく、デフォルト引数や
*argsで代替されることが多い - 現在: IDEの補完機能と組み合わせることで、オーバーロードの定義一覧がポップアップ表示される「シグネチャヘルプ」が当たり前になり、コーディング効率を大きく高めている
オーバーロード vs オーバーライドの違い
「オーバーロード」と「オーバーライド(override)」は名前が似ていてよく混同されますが、目的も仕組みも別物です。
| 比較項目 | オーバーロード | オーバーライド |
|---|---|---|
| 定義する場所 | 同一クラス内 | 継承した子クラス |
| いつ決まるか | コンパイル時 | 実行時 |
| 引数リスト | 変える必要あり | 同じでよい |
| 目的 | 同名メソッドの便利な使い分け | 親の振る舞いを子が上書き |
| ポリモーフィズムの種類 | 静的 | 動的 |
語呂合わせで覚える!
「ロード(load)は引数の荷を変える、ライド(ride)は乗り換え(継承)で変わる」
- Over-load:荷物(引数)を変えて同じ名前を使い回す
- Over-ride:別のクラスに乗り換えて上書きする
実務での使われ方
システム発注・設計の立場で知っておきたいポイントをまとめます。
① APIやライブラリの使いやすさに直結する
オーバーロードをうまく使うと、呼び出し側が引数の型を意識しなくても同じメソッド名で呼べます。開発者の学習コストが下がり、コードのミスも減ります。
② コンストラクタオーバーロードはよく使われる
オブジェクトを生成するコンストラクタでも多用されます。「全項目指定」「必須項目のみ」のように初期化方法を複数用意するのが定番です。
class User {
User(String name) { ... } // 名前だけで生成
User(String name, int age) { ... } // 名前と年齢で生成
User(String name, int age, String email) { ... } // 全部指定
}
③ Pythonではデフォルト引数・型ヒントで代替
Pythonは動的型付けのため従来のオーバーロードはありませんが、デフォルト引数や functools.singledispatch で似たことができます。
関連用語
- ./048-override.md — オーバーライド:継承関係で親クラスのメソッドを子クラスが上書きする仕組み
- ./050-polymorphism.md — ポリモーフィズム:同一インターフェースで複数の型・振る舞いを扱う概念
- ./051-class.md — クラス:オブジェクトの設計図。メソッドやフィールドをまとめた単位
- ./052-method.md — メソッド:クラスに定義された関数・処理の単位
- ./053-constructor.md — コンストラクタ:オブジェクト生成時に呼ばれる初期化メソッド
- ./054-inheritance.md — 継承:既存クラスの機能を引き継いで新しいクラスを作る仕組み
- ./055-static-dispatch.md — 静的ディスパッチ:コンパイル時に呼び出す処理を決定する仕組み