クラス

ここからは,ラーメンを例に,オブジェクトをとらえていきたい.まずは,基本となるラーメンのクラスをつくる.ラーメンの固さ,麺の量,味を指定して,ラーメンのインスタンスを生成できるクラスを作る.

ここで,味を決めるTasteは列挙型(enum)であり,一連の値を定義して,その中から選ぶことができる.したがって,定義された値以外を選ぶことができないので,一定の選択肢から選ぶ時などは,便利である

enum Taste
{
    しょうゆ,みそ
}
public class Ramen
{
    private int katasa;//1:固い,2:普通,3:柔い
    private int ryou;//1-10
    private Taste soup;
    Ramen()
    {
        System.out.println("ラーメンつくるよ");
    }
    public void setMen(int ryou)
    {
        this.ryou = ryou;
        System.out.println("量:" + ryou);
    }
    public void setKatasa(int katasa)
    {
        this.katasa = katasa;
        System.out.println("固さ:" + katasa);
    }
    public void setSoup(Taste taste)
    {
        this.soup = taste;
        System.out.println("スープ:" + this.soup);
    }
    public void checkRamen()
    {
        System.out.print("量:" + ryou);
        System.out.print("固さ:" + katasa);
        System.out.println("スープ:" + soup);
    }
}

Ramenクラスをインスタンス化して麺の量,麺の固さ,スープの味を指定して,ラーメンを作る.

public class Main
{
    public static void main(String[] args)
    {
        //ラーメンくれ
        System.out.println("===ラーメン===");
        Ramen ramen1 = new Ramen();
        ramen1.setMen(5);
        ramen1.setKatasa(2);
        ramen1.setSoup(Taste.しょうゆ);
        ramen1.checkRamen();
        //固めん10盛りのみそラーメンくれ
        System.out.println("===固めん,10盛り,みそ===");
        Ramen ramen2 = new Ramen();
        ramen2.setKatasa(1);
        ramen2.setMen(10);
        ramen2.setSoup(Taste.みそ);
        ramen2.checkRamen();
    }
}
===ラーメン===
ラーメンつくるよ
量:5
固さ:2
スープ:しょうゆ
量:5,固さ:2,スープ:しょうゆのラーメンです
===固めん,10盛り,みそ===
ラーメンつくるよ
固さ:1
量:10
スープ:みそ
量:10,固さ:1,スープ:みそのラーメンです

ラーメンをインスタンスして,麺のかたさ,麺の量,スープの味を指定してラーメンが出来上がる.

thisとスコープ

ここで,メソッドを用いて,麺の量や硬さ,スープの味を指定するときに,用いている「this」について,考えてみる.

public class Ramen
{
    protected int ryou;//1-10
    public void setMen(int ryou)
    {
        this.ryou= ryou;
        System.out.println("量:" + ryou);
    }
}

ryouという変数が,メソッドの引数と,クラスのフィールドの2種類存在していることに気づくだろうか.setMen内では,二つの「ryou」が存在しているが,良いのだろうか. 変数にはスコープと呼ばれる,有効範囲が決められていて,それぞれの変数が有効である範囲と,優先度が決められている.

変数の有効範囲は,「{ }」で囲まれた範囲である.RamenクラスのryouはRamenクラス内で有効である.他方,setMenクラスのryouはsetMenメソッド内のみで有効である.仮引数でなく,setMen内で指定した変数も同様である.


ここで疑問なのは,setMenの範囲では,二つのryouが有効ではないかということである.そのとおり,どちらも有効であるただし,優先順位がある.局所的な変数が優先である.すなわち,Ramenクラスのフィールドryouよりも,setMenでの仮引数ryouの方が,狭い範囲で有効であるので,setMenの範囲では,仮引数のryouの方が優先される.したがってsetMen内で単純に「ryou」を指定すると,setMen内のryouを意味する.

ここで,仮引数で得た値をフィールドに代入したい場合にはどうすれば良いだろうか.その時には,クラスのフィールドであることを明示すればよい.今存在するクラスを指定するキーワードが「this」である.

以下のthis.ryou = ryouは,「クラスのフィールドのryou = 局所変数のryou」という意味である.
public class Ramen
{
    protected int ryou;//1-10
    public void setMen(int ryou)
    {
        this.ryou= ryou;
    }
}

課題

量を8,固さを1,スープをしお となる塩ラーメンを作れるように,プログラムを改編せよ.さらに,塩ラーメンを実体化して確認せよ.

共通するクラス