静的フィールド・静的メソッド

これまで設定してきたフィールドやメソッドは,インスタンスそれぞれに設定されるように定義してきたので,インスタンス化した時に,生成されるインスタンスごとに独立して設けられる. 


一方で,クラスで共有する変数を定義することができる.それが静的フィールドである.例として,作成するスタックのインスタンス数を記憶しておくための変数を定義する.


変数を定義するだけでは何も活用されないので,スタックを生成するとき,すなわち,コンストラクタが呼ばれるときに,カウントアップするように設定する.


class Stack
{
    private int volume;
    private int data[];
    static int defaultSize = 5;
    static int stackCount = 0;
    //標準サイズのためのコンストラクタ
    public Stack()
    {
        this(defaultSize);
    }
    //サイズ指定のためのコンストラクタ
    public Stack(int stackSize)
    {
        data = new int[stackSize];
        System.out.println(data.length + "個分のスタック生成");
        stackCount++;
    }
    //データ追加メソッド
    public boolean push(int number)
    {
        if(number > 0)
        {
            if(volume < data.length)
            {
                data[volume] = number;
                volume++;
                return true;
            }
            else
            {
                System.out.println("stack overflow");
                return false;
            }
        }
        else
        {
            System.out.println("input value invalid");
            return false;
        }
    }
    //データ取得メソッド
    public int pop()
    {
        int value;
        if(volume > 0)
        {
            value = data[volume -1];
            data[volume -1] = 0;
            volume--;
        }
        else
        {
            value = -1;
        }
        return value;
    }
    //状態表示メソッド
    public void printStack()
    {
        System.out.print("|");
        for(int i=0; i < data.length; i++)
        {
             printStack(i);
             System.out.print("|");
        }
        System.out.println("");
    }
    //個別の状態表示メソッド
    private void printStack(int i)
    {
        System.out.print(data[i]);
    }
}

設定した静的フィールドの値を確認するためのステートメントを実行して,内容を表示する. このとき,気をつけなければならないのは,静的フィールドのアクセス方法である.

これまでは,生成したインスタンスのフィールドにアクセスするので,
(インスタンスを表す変数名).(インスタンス変数)
のようにアクセスしていた.
しかし,静的フィールドは,インスタンスに寄らない,クラスに設けられる変数であるので,インスタンスを特定せずにアクセスする必要がある.そのため,
(クラス名).(静的フィールド名)
となる.
public class Main
{
    public static void main(String[] args)
    {
        Stack tower = new Stack();
        System.out.println(Stack.stackCount + "個目のスタックです");
        Stack tower10 = new Stack(10);
        System.out.println(Stack.stackCount + "個目のスタックです");
    }
}

実行した結果は以下のようになる.

5個分のスタック生成
1個目のスタックです
10個分のスタック生成
2個目のスタックです

静的フィールドと同様に,静的なメソッドも定義することができる.静的メソッドも,インスタンスではなく,クラスに対して定義されるため,インスタンス化されなくても,実行することができる. 注意として,インスタンス化されなくても実行でき,クラスに属するメソッドであるため,インスタンス変数を扱うことはできない.


以下の例では,スタックを作成するごとに,コンストラクタにて,何個のスタックを作成したかをカウントしている.その数えた数を返すメソッドを静的メソッドとして設けている.

class Stack
{
    int volume;
    int data[];
    final static int defaultSize = 5;
    static private int stackCount = 0;
    //標準サイズのためのコンストラクタ
    public Stack()
    {
        this(defaultSize);
    }
    //サイズ指定のためのコンストラクタ
    public Stack(int stackSize)
    {
        data = new int[stackSize];
        System.out.println(data.length + "個分のスタック生成");
        stackCount++;
    }
    //データ追加メソッド
    public boolean push(int number)
    {
        if(number > 0)
        {
            if(volume < data.length)
            {
                data[volume] = number;
                volume++;
                return true;
            }
            else
            {
                System.out.println("stack overflow");
                return false;
            }
        }
        else
        {
            System.out.println("input value invalid");
            return false;
        }
    }
    //データ取得メソッド
    public int pop()
    {
        int value;
        if(volume > 0)
        {
            value = data[volume -1];
            data[volume -1] = 0;
            volume--;
        }
        else
        {
            value = -1;
        }
        return value;
    }
    //状態表示メソッド
    public void printStack()
    {
        System.out.print("|");
        for(int i=0; i < data.length; i++)
        {
             printStack(i);
             System.out.print("|");
        }
        System.out.println("");
    }
    //個別の状態表示メソッド
    private void printStack(int i)
    {
        System.out.print(data[i]);
    }
    //生成したスタックの個数を取得するためのメソッド
    public static int stackVolume()
    {
        return stackCount;
    }
}
class Main
{
    public static void main(String[] args)
    {
        Stack tower = new Stack();
        System.out.println(Stack.stackVolume() + "個目のスタックです");
        Stack tower10 = new Stack(10);
        System.out.println(Stack.stackVolume() + "個目のスタックです");
    }
}

課題

キューのプログラムに対して,キューを何個生成したかをカウントするための静的変数をキュークラスに定義せよ.さらに,生成した個数を返すためのメソッドを用意し,メインクラスから実行できるようにせよ.

メインクラスでは,キューを何個生成したか確認して,静的変数として動作していることを確認せよ.

静的変数・メソッド