いまさら聞けないJavaによるオブジェクト指向の常識プログラマーの常識をJavaで身につける(11)(3/5 ページ)

» 2008年05月08日 00時00分 公開
[伊賀敏樹, 山本耕司株式会社 NTTデータ ビジネスブレインズ]

「汎化・特化」、Javaでは多くの場合「継承」

 ところで、ラーメン屋では、ラーメンだけではなく、チャーシューメンとねぎラーメンも作っているとします。

図4 チャーシューメンとねぎラーメン 図4 チャーシューメンとねぎラーメン(こちらの図はJavaプログラミング[アプリケーション編]ステップアップラーニング』(技術評論社)で使われた図を引用して再作成したものです)

 ラーメン、チャーシューメン、ねぎラーメンを見比べてみると、とても似ていることが分かります。ラーメンに“チャーシュー”を載せると「チャーシューメン」、ラーメンに“ねぎ”を載せると「ねぎラーメン」であると考えることができますね(こだわりラーメン屋では、チャーシューメンとねぎラーメンには独自のレシピがあるかもしれません。しかし話を単純化するために、それら特殊レシピについては考慮しないこととします)。

 ここでは、Java言語のextends継承)を用いてチャーシューメン・クラスとねぎラーメン・クラスを記述してみます。

CharSiuRamen.java
/**
* チャーシューメン・クラス
*/

public class CharSiuRamen extends Ramen {
    /**
    * ラーメンのトッピング
    */

    private String fTopping = null;

    /**
    * チャーシューメン・クラスのコンストラクタ
    */

    public CharSiuRamen() {
        // トッピングに「チャーシュー」をセット
        fTopping = "チャーシュー";
    }
    /**
    * ラーメンを表示
    */

    public void showCharSiuRamen() {
        System.out.println("ラーメンを表示");
        System.out.println(" トッピング: " + getTopping());
        System.out.println(" スープ : " + getSoup());
    }
    /**
    * ラーメンのトッピングを取得
    *
    * @return トッピング
    */

    public String getTopping() {
        return fTopping;
    }
}

LeekRamen.java
/**
* ねぎラーメン・クラス
*/

public class LeekRamen extends Ramen {
    /**
    * ラーメンのトッピング
    */

    private String fTopping = null;

    /**
    * ねぎラーメン・クラスのコンストラクタ
    */

    public LeekRamen() {
        // トッピングに「ねぎ」をセット
        fTopping = "ねぎ";
    }
    /**
    * ラーメンを表示
    */

    public void showLeekRamen() {
        System.out.println("ラーメンを表示");
        System.out.println(" トッピング: " + getTopping());
        System.out.println(" スープ : " + getSoup());
    }
    /**
    * ラーメンのトッピングを取得
    *
    * @return トッピング
    */

    public String getTopping() {
        return fTopping;
    }
}

 この例では、どのラーメンもスープは同じ「とんこつ」です。このような、共通した性質を親クラスにまとめることを「汎化」と呼びます。逆に、チャーシューメン、ねぎラーメンは、ラーメンとトッピングが異なります。このように、共通していない性質を子クラスに付け加えることを「特化」と呼びます。

 上記のソースコードでは、ラーメン・クラス、チャーシューメン・クラス、ねぎラーメン・クラスに、以下のような関係があるということが表現されています。

  • ラーメン・クラスはチャーシューメン・クラスを汎化したもの
  • ラーメン・クラスはねぎラーメン・クラスを汎化したもの
  • チャーシューメン・クラスはラーメン・クラスを特化したもの
  • ねぎラーメン・クラスはラーメン・クラスを特化したもの

上級者向けの注意!

「汎化」「特化」は、Java言語上では「継承」により表現されることがよくありますが、場合により、「委譲」として実装されることもあります。


ラーメン料理人クラスにメソッドを追加

 ラーメンの品ぞろえが増えたので、ラーメン料理人クラスにメソッドを追加して、さまざまなラーメンの注文を受けられるようにしましょう。

図5 作れるレシピが増えたラーメン屋で働く料理人 図5 作れるレシピが増えたラーメン屋で働く料理人(こちらの図はJavaプログラミング[アプリケーション編]ステップアップラーニング』(技術評論社)で使われた図を引用して再作成したものです)

 ラーメン、チャーシューメン、ねぎラーメンの3つの商品が必要です。

RamenCook.java
public class RamenCook {
    /**
    * ラーメンの注文を受ける
    *
    * @return ラーメン・インスタンス
    */

    public Ramen acceptRamenOrder() {
        // ラーメン・クラスからラーメン・クラスのインスタンスを作成
        final Ramen ramen = new Ramen();

        // 作成されたラーメン・インスタンスをreturnする
        return ramen;
    }

    /**
    * チャーシューメンの注文を受ける
    *
    * @return チャーシューメン・インスタンス
    */

    public CharSiuRamen acceptCharSiuRamenOrder() {
        // ラーメン・クラスからラーメン・クラスのインスタンスを作成
        final CharSiuRamen ramen = new CharSiuRamen();

        // 作成されたチャーシューメン・インスタンスをreturnする
        return ramen;
    }

    /**
    * チャーシューメンの注文を受ける
    *
    * @return ねぎラーメン・インスタンス
    */

    public LeekRamen acceptLeekRamenOrder() {
        // ラーメン・クラスからラーメン・クラスのインスタンスを作成
        final LeekRamen ramen = new LeekRamen();

        // 作成されたねぎラーメン・インスタンスをreturnする
        return ramen;
    }
}

 では、早速ねぎラーメンを注文してみましょう。

図6 ねぎラーメンを注文するラーメン屋のお客 図6 ねぎラーメンを注文するラーメン屋のお客(こちらの図はJavaプログラミング[アプリケーション編]ステップアップラーニング』(技術評論社)で使われた図を引用して再作成したものです)
Customer.java
public class Customer {
    public static void main(final String[] args) {
        // ラーメン料理人・インスタンスを作成する
        final RamenCook cook = new RamenCook();

        // ラーメン料理人にねぎラーメンを注文する
        final LeekRamen ramen = cook.acceptLeekRamenOrder();

        // 出来上がったねぎラーメンを表示する
        ramen.showLeekRamen();
    }
}

 ねぎラーメンを注文するメソッドを呼び出すように変更し、ねぎラーメンの表示メソッドを呼び出します。

ラーメンを表示
 トッピング : ねぎ
 スープ : とんこつ
実行結果(コンソール出力)

 ちゃんと、ねぎラーメンが出来上がっていますね。

 続いて次ページでは、メッセージ・パッシング、カプセル化、多態性について解説します。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。