オーバーロードとオーバーライド

オーバーロード、オーバーライド Java

名前は似ていますが、全く異なるものです。

オーバーロード・・・1つのクラスに同じ名前のメソッドを複数定義すること

オーバーライド・・・スーパークラスで定義されたメソッドをサブクラスで再定義すること

スーパークラスとサブクラスが何か分からない人は下記の記事を参照してください。

継承とは?
継承とは、あるクラスの特徴を別のクラスが受け継ぐことを言います。 この時、既存のクラスをスーパークラス(親クラス)、特徴を受け継いだクラスをサブクラス(子クラス)、と言います。 継承のイメージ 自動車と消防車を例にとって考えてみましょう。 ...

オーバーロード

オーバーロードは、1つのクラスに同じ名前のメソッドを複数定義することです。

書き方

オーバーロードしているプログラムを見てみましょう。

class Calculation{
 //掛け算を行うメソッド
 public int multiple(int num1, int mum2){
  
  return num1 * num2;
 }

 //オーバーロード
 public int multiple(int num1, int num2, int num3){
  return num1 * num2 * num3;
 }
}

3行目でmultipleメソッドを定義し、8行目で再び同じ名前のmultipleメソッドを定義しています。

3行目と8行目のmultipleメソッドで異なる点は、引数の数です。

同じメソッド名でも、引数の型や個数、順番が異なれば、別のメソッドとして定義されます。
オーバーロードする際には、引数の型や個数、順番を変える必要があります。

以下にオーバーロードできる例と、できない例を挙げておきます。

//元のメソッド
public void print(int num, String a){
  
 System.out.println(a + num);
}

//オーバーロードできる例

//引数のデータ型が異なる
public void multiple(String num, String a){

  System.out.println(a + num);
}

//引数の個数が異なる
public void multiple(int num, String a, String b){
  
  System.out.println(a + num + b);
}

//引数の順番が異なる
public void multiple(String a, int num){
  
  System.out.println(a + num);
}


//オーバーロードできない例

//引数は同じで、中身が異なる
public void multiple(int num, String a){

 num = num +10;
 System.out.println(a + num);
}

//修飾詞が異なる
private void multiple(int num, String a){

 System.out.println(a + num);
}

//戻り値の型だけが異なる
public int mutiple(int num, String a){

 return num + Integer.parseInt(a);
}


メソッドを呼び出す際には、引数の型や個数、順番で呼び出すメソッドを自動的に判断してくれます。

先ほどのCalculationクラスのメソッドをTestクラスで呼び出す例を見てみましょう。

class Calculation{
 //掛け算を行うメソッド
 public int multiple(int num1, int mum2){
  
  return num1 * num2;
 }

 //オーバーロード
 public int multiple(int num1, int num2, int num3){
  return num1 * num2 * num3;
 }
}
class Test{
 public static void main(String args[]){
  Calculation cal = new Calculation();
  
  //2数の掛け算...Calculationクラスの3行目のメソッドが呼ばれる
  cal.multiple(10, 20);

  //3数の掛け算...Calculationクラスの8行目のメソッドが呼ばれる
  cal.multiple(10, 20, 30);

Testクラスの6行目のメソッド呼び出しでは、引数が2つ渡されているので、Calculationクラスで3行目に定義したメソッドが呼び出されています。

一方、Testクラスの9行目のメソッド呼び出しでは、引数が3つ渡されているので、Calculationクラスで8行目に定義したメソッドが呼び出されています。

メリット

オーバーロードのメリットは、同じ用途のメソッドを同じ名前で統一することができる点です。

皆さんが普段使っているSystem.out.printlnメソッドを例に見てみましょう。

//int型のデータを表示
System.out.println(100);

//double型のデータを表示
System.out.println(10.4);


//boolean型のデータを表示
System.out.println(true);

//String型のデータを表示
System.out.println("Hello World");

このように、引数にどのような型のデータを渡しても正しく表示されます。

これは、System.out.printlnメソッドが様々なデータ型を引数としてオーバーロードされているからです。

もし、オーバーロードされていない場合、次のようになります。

//int型のデータを表示
System.out.printlnInt(100);

//double型のデータを表示
System.out.printlnDouble(10.4);


//boolean型のデータを表示
System.out.printlnBoolean(true);

//String型のデータを表示
System.out.printlnString("Hello World");

表示したいデータの型ごとに名前を変えなければいけないのです。

オーバーロード機能があることで、「コンソールに表示する」という用途のメソッドを同じ名前で管理することができているのです。

オーバーライド

オーバーライドは、スーパークラスで定義されたメソッドをサブクラスで再定義することです。

書き方

スーパークラスCarクラスと、サブクラスFireTruckクラスを定義します。

CarクラスのrunメソッドをFireTruckクラスでオーバーライドする例を見てみましょう。

Carクラス(スーパークラス)

class Car{
 
 //「走る」処理
 public void run(){
  System.out.println("走るよ");
 }
 
 //「止まる」処理
 public void stop(){
  System.out.println("止まるよ");
 }
}


FireTruckクラス(サブクラス)

class FireTruck extends Car{
 //オーバーライド
 public void run(){
  System.out.println("信号を無視して走るよ");
 }
 
 //「放水する」処理
 public void water(){
  System.out.println("放水するよ");
 }
}

Carクラス(スーパークラス)ですでに定義したrunメソッドを、FireTruckクラス(サブクラス)で再び定義しなおしています。

では、実際にメソッドを呼び出してみましょう。

class Test{
 public static void main(String args[]){
  Car car = new Car();
  FireTruck ft = new FireTruck();

  //「走るよ」が表示される
  car.run();

  //「信号を無視して走るよ」が表示される
  ft.run();

オーバーライドすることで、FireTruckクラスのオブジェクトからrunメソッドを呼び出すと、FireTruckクラスで再定義したrunメソッドが呼び出されます


オーバーライドを行う条件には次の4つがあります。

  • メソッド名が同じ
  • 引数の型と数、順番が同じ
  • 戻り値の型が同じ
  • アクセルレベルが同じか、元のメソッドよりも制限が緩い

先ほどのCarクラス、FireTruckクラスのrunメソッドに注目して、オーバーライドできない例をいくつか挙げます。

Carクラス(スーパークラス)

class Car{
 
 //「走る」処理
 public void run(double speed, String a){
  System.out.println(a);
  System.out("時速" + speed + "kmで走るよ");
 }
}


FireTruckクラス(サブクラス)

class FireTruck extends Car{
 //オーバーライドできる例

 //メソッド名が異なる
 public void runFireTruck(double speed, String a){
  System.out.println(a);
  System.out("信号を無視して時速" + speed + "kmで走るよ");
 }

 //引数の型が異なる
 public void run(int speed, String a){
  System.out.println(a);
  System.out("信号を無視して時速" + speed + "kmで走るよ");
 }

 //引数の数が異なる
 public void run(double speed, String a, String b){
  System.out.println(a + b);
  System.out("信号を無視して時速" + speed + "kmで走るよ");
 }

 //引数の順番が異なる
 public void run(String a, double speed){
  System.out.println(a);
  System.out("信号を無視して時速" + speed + "kmで走るよ");
 }

 //戻り値の型が異なる
 public String run(double speed, String a){
  return ("信号を無視して時速" + speed + "kmで走るよ");
 }

 //スーパークラスよりアクセス制限が厳しい
 private void run(double speed, String a){
  System.out.println(a);
  System.out("信号を無視して時速" + speed + "kmで走るよ");
 }
}

分かりづらいのは1番最後のアクセスレベルのところだと思います。

要は、スーパークラスでpublicなメソッドを、サブクラスでprivateにはできないということです。

まとめ

オーバーロード・・・1つのクラスに同じ名前のメソッドを複数定義すること条件

  • 条件
    1. 同一クラス内で定義
    2. メソッド名が同じ
    3. 引数の型、数、順番が異なる
  • メリット
    • 同じ用途のメソッドを1つの名前で管理できる

オーバーライド・・・スーパークラスで定義されたメソッドをサブクラスで再定義すること

  • 条件
    1. メソッド名が同じ
    2. 引数の型、数、順番が同じ
    3. 戻り値の型が同じ
    4. アクセスレベルが同じか、元よりも制限が緩い
  • メリット
    • 同一メソッドでもクラスによって、挙動を変えられる

コメント

タイトルとURLをコピーしました