「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典イメージぴよ画像「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

オーバーロード

pointこの用語のポイント

point同じ名前の関数(メソッド)を複数個、定義するよ

point引数の違いで区別するよ

スポンサーリンク

簡単に書くよ

オーバーロード(英:overload)とは

名前は同じだけど引数(プログラムや関数に入れる値)の数とか型(変数の種類)とかが違う関数(処理のまとまり)を複数個、用意すること
です。


image piyo

詳しく書くよ

順番に見ていきましょう。
まずは予備知識として

変数
変数の型
関数
引数(ヒキスウ)
オブジェクト指向
メソッド


について説明します。
「そんなの説明されなくても知ってるよ!」な人は適当に読み飛ばしてください。

変数は「プログラミング言語における『値を入れておく箱』」です。
処理の途中で値を入れたり、逆に取り出したりできます。

オーバーロード

変数の型は「この箱(変数)には、どんな種類の物を入れていいですよ」な決まりです。

オーバーロード2

例えば、そうですね。
手ごろな大きさのダンボール箱が あったとしましょう。

オーバーロード3

ピヨ太君がやってきて、その箱にマジックで大きく「食べ物用」と書きました。

オーバーロード4

「食べ物用」と書いたので、このダンボールに入れていいのは食べ物だけです。
食べ物以外を入れようとすると、ピヨ太君にメッチャ怒られます。

オーバーロード5

この話におけるダンボール箱が「変数」です。
マジックで書いた「食べ物用」が「変数の型」になります。

オーバーロード6

変数の型には、いろいろな種類があります。
数字を入れられる箱、文字を入れられる箱、文字列を入れられる箱、いろいろです。

関数は「何かを入れると何かをやって何かを返してくれる、処理のまとまり」です。
一般的には、入力を受けて処理をやり、その結果として出力があります。

オーバーロード7

引数は「プログラムや関数に渡す値」です。

オーバーロード8

ちょっと汚い話で恐縮ですが、人間は ご飯を食べて、ウンチを出します。

オーバーロード9

人間を関数だとすれば、ご飯に相当するものが引数です。
あと、ついでなので書いておくと、ウンチに相当するものは戻り値です。

オーバーロード10

少し本題とは外れますが「オブジェクト指向」と「メソッド」の説明もしておきます。

オブジェクト指向は「『モノ』に注目した考え方」です。
「どんなやつで、どう動く」に注目した考え方です。

オーバーロード11

詳細は、用語「オブジェクト指向」の説明を ご覧ください。

オーバーロード12

オブジェクト指向の理念に沿って作られたプログラミング言語を「オブジェクト指向プログラミング言語」と言います。
有名どころでは、Javaなんかがオブジェクト指向プログラミング言語です。

オブジェクト指向プログラミング言語では

クラス
インスタンス
オブジェクト


の3つの用語が よく出てきます。
この3つは とても大事です。
ざっくりとで良いので関係性を覚えておいてください。

専門家の人からは怒られそうですが、ものすごい大雑把に説明すると

クラス:設計図
インスタンス:実際に作った物
オブジェクト:モノ(クラスとかインスタンスとかを、ふんわりと表現したもの)


です。

クラスは「設計図」です。
「それって、どんなもの?」を示しています。
ピヨ太君の頭の中にある「ピヨピヨ時計は こんな感じだな」がクラスです。

オーバーロード13

インスタンスは「実際に作ったもの」です。
クラス(設計図)に書かれた「それって、どんなもの?」を形にしたものを指します。
実際に作ったピヨピヨ時計がインスタンスです。

オーバーロード14

オブジェクトは……モノですよ、モノ。
結構ざっくりとした使われ方をする用語です。
「クラスとかインスタンスを ふんわりと表現したもの」くらいに解釈してください。
よく分からない人は忘れてしまって かまいません。

オーバーロード15

メソッドは、教科書的な説明をすれば「オブジェクトの『操作』を定義したもの」です。
ただし、今回は

クラス内に定義した関数のこと

と解釈してください。
その方がイメージしやすいと思います。

以上を踏まえて

引数の数とか型が違うけど同じ名前の関数(メソッド)を複数個、定義する

のが「オーバーロード」です。
どの関数が実際に呼び出されるかは、どのような引数が指定されたかで判断されます。

……とか言葉で説明されるよりも、実際の処理を見た方が分かりやすいかもしれませんね。

例えば、そうですね。
Javaで書いた以下のソースコード(人間語で書いたプログラムの元ネタ)が あったとしましょう。

class TestSub{
  public static void testMethod(){
    System.out.println("テストメソッド その1");
  }

  public static void testMethod(String str1){
    System.out.println("テストメソッド その2");
  }

  public static void testMethod(Integer int1){
    System.out.println("テストメソッド その3");
  }

  public static void testMethod(Integer int1, Integer int2){
    System.out.println("テストメソッド その4");
  }
}

//主処理
public class test{
  public static void main(String[] args){
    //テストメソッド実行
    TestSub.testMethod();
    TestSub.testMethod("a");
    TestSub.testMethod(1);
    TestSub.testMethod(1, 2);
  }
}


まずは

class TestSub{
  public static void testMethod(){
    System.out.println("テストメソッド その1");
  }

  public static void testMethod(String str1){
    System.out.println("テストメソッド その2");
  }

  public static void testMethod(Integer int1){
    System.out.println("テストメソッド その3");
  }

  public static void testMethod(Integer int1, Integer int2){
    System.out.println("テストメソッド その4");
  }
}


の部分に注目してください。

「TestSub」クラスの中には同じ名前のメソッド「testMethod()」が4個も定義されています。
ただし、それぞれの引数の数や型は違います。
どれ1つとして同じものは ありません。

次に

    //テストメソッド実行
    TestSub.testMethod();
    TestSub.testMethod("a");
    TestSub.testMethod(1);
    TestSub.testMethod(1, 2);


の部分に注目してください。

呼び出しているメソッドは、すべて「TestSub」クラスで定義されている「testMethod()」メソッドです。
ただし、呼び出すときに指定している引数の数や型が違います。

この処理を実行すると、画面上に

テストメソッド その1
テストメソッド その2
テストメソッド その3
テストメソッド その4


と表示されます。

引数の数や型が一致する「testMethod()」メソッドが実行されていますよね。

このような

引数が違う同じ名前の関数(メソッド)を複数個、定義する

のがオーバーロードです。

オーバーロードの主な使いどころは

引数を変えて同じ処理をやりたい場合

です。

例えば

1.2つの数の足し算をするメソッド
2.3つの数の足し算をするメソッド
3.4つの数の足し算をするメソッド


を用意したいとしましょう。

そんなときはメソッドの名前を変えて

//計算クラス
class Calc{
public static Integer addition1(Integer int1, Integer int2){
    return (int1 + int2);
  }

  public static Integer addition2(Integer int1, Integer int2, Integer int3){
    return (int1 + int2 + int3);
  }

  public static Integer addition3(Integer int1, Integer int2, Integer int3, Integer int4){
    return (int1 + int2 + int3 + int4);
  }
}

//主処理
public class test{
  public static void main(String[] args){

    //足し算実行
    System.out.println("1+2=" + Calc.addition1(1, 2));
    System.out.println("1+2+3=" + Calc.addition2(1, 2, 3));
    System.out.println("1+2+3+4=" + Calc.addition3(1, 2, 3, 4));
  }
}


としても間違いでは ありません。

ですが、ちょっと考えてみてください。

やりたいことは全部「足し算をする」です。
どうせだったら「足し算メソッド」を1つ用意して、そいつで全部やれた方がスッキリしますよね。

そんなときはオーバーロードを使って

//計算クラス
class Calc{
public static Integer addition(Integer int1, Integer int2){
    return (int1 + int2);
  }

  public static Integer addition(Integer int1, Integer int2, Integer int3){
    return (int1 + int2 + int3);
  }

  public static Integer addition(Integer int1, Integer int2, Integer int3, Integer int4){
    return (int1 + int2 + int3 + int4);
  }
}

//主処理
public class test{
  public static void main(String[] args){

    //足し算実行
    System.out.println("1+2=" + Calc.addition(1, 2));
    System.out.println("1+2+3=" + Calc.addition(1, 2, 3));
    System.out.println("1+2+3+4=" + Calc.addition(1, 2, 3, 4));
  }
}


のようにするのです。

こうしておけば「足し算は『addition()』メソッドでやる」と統一されます。
スッキリしました。

また「引数の数が3個だから……呼び出すのは『addition2()』か」とか、いちいち考える必要がありません。
不具合が入り込む可能性も減るでしょう。

これがオーバーロードの使い道(の一例)です。

なお「addition()」メソッドをオーバーロードするサンプルは、さらに横着して以下のように書くこともできます。

//計算クラス
class Calc{
public static Integer addition(Integer int1, Integer int2){
    return addition(int1, int2, 0);
  }

  public static Integer addition(Integer int1, Integer int2, Integer int3){
    return addition(int1, int2, int3, 0);
  }

  public static Integer addition(Integer int1, Integer int2, Integer int3, Integer int4){
    return (int1 + int2 + int3 + int4);
  }
}

//主処理
public class test{
  public static void main(String[] args){

    //足し算実行
    System.out.println("1+2=" + Calc.addition(1, 2));
    System.out.println("1+2+3=" + Calc.addition(1, 2, 3));
    System.out.println("1+2+3+4=" + Calc.addition(1, 2, 3, 4));
  }
}


書き換えた後の処理を見て「同じ名前のメソッドが、たくさん出てきて、ややこしい!」と思う人もいるでしょう。
「実際の足し算をする箇所が1か所になった。美しい!」と感じる人もいるでしょう。

あるいは「引数の数が何個になっても対応できるようにしておこう!」とか考えて、以下のように書く人もいるはずです。
※今までのサンプルより少しややこしいです。頑張って読み解いてください。

import java.util.ArrayList;

//計算クラス
class Calc{
  public static Integer addition(Integer int1, Integer int2){
    ArrayList<Integer> al = new ArrayList<Integer>();

    al.add(int1);
    al.add(int2);

    return addition(al);
  }

  public static Integer addition(Integer int1, Integer int2, Integer int3){
    ArrayList<Integer> al = new ArrayList<Integer>();

    al.add(int1);
    al.add(int2);
    al.add(int3);

    return addition(al);
  }

  public static Integer addition(Integer int1, Integer int2, Integer int3, Integer int4){
    ArrayList<Integer> al = new ArrayList<Integer>();

    al.add(int1);
    al.add(int2);
    al.add(int3);
    al.add(int4);

    return addition(al);
  }

  public static Integer addition(ArrayList<Integer> al){
    Integer ret = 0;

    //リスト内の要素を足し算
    for(int i= 0; i < al.size(); i++){
      ret += al.get(i);
    }

    return ret;
  }

}

//主処理
public class test{
  public static void main(String[] args){

    //足し算実行
    System.out.println("1+2=" + Calc.addition(1, 2));
    System.out.println("1+2+3=" + Calc.addition(1, 2, 3));
    System.out.println("1+2+3+4=" + Calc.addition(1, 2, 3, 4));
  }
}


ポイントは

  public static Integer addition(ArrayList<Integer> al){
    Integer ret = 0;

    //リスト内の要素を足し算
    for(int i= 0; i < al.size(); i++){
      ret += al.get(i);
    }

    return ret;
  }


の部分ですね。
引数をArrayList(要素の数が可変な配列みたいなもの)にして、ArrayList内の全要素を足し算するようにしておくことで、引数が何個になっても対応できます。

同じ処理でもいろいろな書き方ができるのが、プログラミングの難しいところでもあり楽しいところでもありますね。


image piyo2

一言でまとめるよ

まぁ「オーバーロード」って単語が出てきたら「引数(プログラムや関数に入れる値)が違う同じ名前の関数(処理のまとまり)(メソッド(「オブジェクトの操作を定義したもの」だけど、動きとしては関数と同じ))を複数個、定義するんだな~」と お考えください。

一番上に戻るよ
スポンサーリンク
書籍画像048
書籍画像059

おまけ

■訳してみるよ

「overload(オーバーロード)」の意味は「過負荷」とかです。
IT用語の「overload(オーバーロード)」は日本語では「多重定義」などと訳されたりします。





書籍画像
わわわ説明術コラム
宣伝だよ
「分かった!」と思わせる説明の技術 知識ゼロの相手にも伝わるようになる本【Audible】
AI用語図鑑 ビジネス・開発・試験対策に使える厳選キーワード256
マンガでわかるITパスポート