オーバーロード

メソッドを定義していくと引数は異なりますが似たようなメソッドを作りたい状況が発生します。
プログラミング言語によっては同じ名前のメソッドを定義することは禁止されていたり推奨されていないこともあります。
ですが、Javaでは引数や戻り値が異なれば全く別のメソッドとして認識される為に同じ名前のメソッドが多重定義可能です。
これを(メソッドの)オーバーロードと呼びます。

オーバーロード

メソッドの引数は定義しない、または1以上の引数を定義できました。
この時、順序も含め引数の型が一致している場合に別のメソッドであると言えます。
次は引数の異なるメソッドの一例です。

    public void foo(int a)
    {
    }
    public void foo(int a, boolean b)
    {
    }
    // 引数の順序が異なる場合
    public void foo(boolean bm, int a)
    {
    }

ただし、呼び出し元からは2つのメソッドを区別できない為に引数の名前が異なるメソッドは定義できません。

    public void foo(int a, int b)
    {
    }
    // 引数の名前は異なるが、型の出現順序は同じ
    public void foo(int b, int a)
    {
    }

上記のような2つのメソッドを同じクラスに定義すると、コンパイルエラーとなります。
サブクラスで定義した場合はオーバーライドとなりますが、引数名が逆転しており混乱を招くので避けるべきです。

このように同じクラス内で引数の異なり名前が同じメソッドを定義することをオーバーロードと呼びます。
オーバーロードとオーバーライドは混同しやすいので注意してください。


さて、継承で使用した計算機をオーバーロードを使って修正していきます。
Calculatorクラスでは、商品の価格と数量を追加していく事で合計金額を算出していきました。
これをBookクラスとCompactDiscクラスを引数とするように修正すると次のようになります。
[Calculator.java]

package example04;

// 計算機クラス
public class Calculator
{
    // 合計金額
    private int totalAmount = 0;
    
    // コンストラクタ
    public Calculator()
    {
    }
    
    // 本を追加(本・数量)
    public void addItem(Book book, int num)
    {
        int price = book.getOffPrice() * num;
        totalAmount = totalAmount + price;
    }
    
    // CDを追加(CD・数量)
    public void addItem(CompactDisc cd, int num)
    {
        int price = cd.getOffPrice() * num;
        totalAmount = totalAmount + price;
    }
    
    // 合計金額取得
    public int getTotalAmount()
    {
        return totalAmount;
    }
}

[Example04.java]

package example04;

public class Example04
{
    public static void main(String[] args)
    {
        Calculator calculator = new Calculator();
        
        Book item1 = new Book();
        item1.setPrice(1800);
        calculator.addItem(item1, 1);
        
        Book item2 = new Book();
        item2.setPrice(920);
        calculator.addItem(item2, 2);
        
        CompactDisc item3 = new CompactDisc();
        item3.setPrice(3500);
        calculator.addItem(item3, 1);
        
        System.out.println("合計で" + calculator.getTotalAmount() + "円になります。");
    }
}

同じaddItemというメソッドを定義していますが、片方はBookクラスを引数とし、片方はCompactDiscを引数としている為、呼び出し側では異なるメソッドを同じように使うことができます。
また、数量は基本的に1であるということであれば、次のメソッドを追加できるでしょう。

    // 本を追加(本・数量1)
    public void addItem(Book book)
    {
        addItem(book, 1);
    }
    
    // CDを追加(CD・数量1)
    public void addItem(CompactDisc cd)
    {
        addItem(cd, 1);
    }

このように同じ名前で処理が少しだけ違う処理はオーバーロードを使うことで効率よく記述できるのです。

演習

  1. Calculatorに解説したコードを加え、数量1に対応するメソッドを追加しなさい
  2. 商品を誤って追加した場合に、商品を除外するメソッド(removeItem)を追加しなさい