継承

継承はあるクラスを拡張して新たなクラスを作る機能です。
継承は主に既存クラスの拡張や変更などに用いられる機能ですが、オブジェクト指向プログラミングを学ぶ上で最も基本的な概念となります。

クラスFooがある時、継承を利用してクラスBarを作るにはextendsキーワードを使用して次のように記述します。

public class Foo
{
}
public class Bar extends Foo
{
}

BarはFooを確かに継承したクラスですが、それ以上の特徴はなにもありません。
このように継承自体にはクラスを拡張する以上の意味はありません。

スーパークラスとサブクラス

継承が行われる時、元となるクラスをスーパークラス基底クラス、親クラス)と呼びます。
スーパークラスは継承のベースとなるクラスであり、拡張するクラスとは無関係に振舞います。

また、継承したクラスは、サブクラス派生クラス、子クラス)と呼ばれます。
尚、基底クラスからは幾つでもサブクラスを作ることができます。

public class Poo extends Foo
{
}

しかし、基底クラスを複数持つこと(多重継承)はできません。

この継承関係をクラス図で表すと次のようになります。

このように継承関係などに着目して書く場合、メソッドや変数名は省略されることがあります。

スーパークラス(基底クラス)を変更した場合、全てのサブクラス(派生クラス)に影響があります。

メソッドの拡張

次の例は、商店でのレジを簡単にシミュレートしたクラスと使用例です。
計算機クラス(Calculator)には、商品の単価と数量を登録するメソッドがあり、合計金額が取得できます。
[Calculator.java]

package example04;

// 計算機クラス
public class Calculator
{
    // 合計金額
    private int totalAmount = 0;
    
    // コンストラクタ
    public Calculator()
    {
    }
    
    // 商品を追加(単価・数量)
    public void addItem(int unitPrice, int num)
    {
        int price = unitPrice * 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();
        calculator.addItem(300, 1);
        calculator.addItem(420, 1);
        calculator.addItem(98, 3);
        System.out.println("合計で" + calculator.getTotalAmount() + "円になります。");
    }
}

このクラスは商品の単価と数量を登録していくことで合計金額を求めることが出来ますが、消費税は考慮されていません。
そこで合計金額の5%を消費税として計算して取得できるメソッドgetTaxAmountを追加したいと思います。
ここでCalculatorクラスにメソッドを追加しても良いのですが、継承を利用してメソッドを追加することができます。
[CalculatorWithTax.java]

package example04;

// 計算機クラス
public class CalculatorWithTax extends Calculator
{
    // 消費税(5%)を取得する
    public int getTaxAmount()
    {
        int amount = getTotalAmount();
        return amount * 0.05;
    }
}

[Example04.java]

package example04;

public class Example04
{
    public static void main(String[] args)
    {
        CalculatorWithTax calculator = new CalculatorWithTax();
        calculator.addItem(300, 1);
        calculator.addItem(420, 1);
        calculator.addItem(98, 3);
        System.out.println("合計で" + calculator.getTotalAmount() + "円になります。");
        System.out.println("消費税は" + calculator.getTaxAmount() + "円になります。");
    }
}

このように継承を使用することにより既存のクラスに変更を加えずにメソッド(機能)を追加することができます。
重要な点はスーパークラス(Calculator)には一切の修正を行っていないことです。

演習問題

  1. 新しい税率(10%)に対応する新しい計算機クラス(CalculatorWithNewTax)を作成しなさい
  2. CalculatorWithNewTaxをクラス図で表しなさい
  3. 新しく作成したクラスを使用する為のmainメソッドを含むクラスを作成し実行しなさい