【Java】クラスフィールドとクラスメソッド

クラスフィールドとは

インスタンスに共通の情報を保持する場所としてクラスフィールドと呼ばれるフィールドを宣言することができます。クラスフィールドはクラス変数と呼ばれることもあります。クラスフィールドはクラスの情報を保持する、全てのインスタンスに共通のフィールドです。クラスフィールドはstaticという修飾子が付きます。

例えば、円の面積や円周を求めたい場合、共通して円周率=3.14を使って計算しますよね。そこで定数という形でクラスフィールドを使います。

private static final double PI = 3.14; //円周率


クラスフィールドをつかって円の面積や円周を計算する方法を記述したクラスとメインメソッドのクラスを記述してみます。

public class Circle {
	//クラスフィールド:定数
	private static final double PI = 3.14; //円周率
	
	//フィールド
	private double r;//半径

	//円の面積
    //半径×半径×円周率の値をgetAreaに返します
	public double getArea(){
		return this.r * this.r * PI;
	}
	
	//円周
    //直径×円周率をgetlengthに返します。
	public double getLength(){
		return this.r * 2 *PI; 
	}
	
	//getter & setter
    //setRの引数rをフィールドrに返します
	public void setR(double r) {
		this.r = r;
	}
}
public class Sample {
	public static void main(String[] args) {
		//クラスCircleをインスタンス化、Circle型の変数circleに代入
		Circle circle = new Circle();
		
		//半径をセットする
		circle.setR(5.0);
		
		//面積を表示する
		System.out.println(circle.getArea());
		
		//円周を表示させる
		System.out.println(circle.getLength());
	}
}

クラスメソッドとは

フィールドにインスタンスフィールドとクラスフィールドがあるように、メソッドにもインスタンスメソッドとクラスメソッドがあります。クラスメソッドを宣言するときにもstaticという修飾子が付けられます。
クラスメソッドは特定のインスタンスと関連付けられていません。クラスメソッドのなかで「現在のインスタンス」を示すthisやsuperを使うとコンパイルエラーになります。
インスタンスメソッドとクラスメソッドの使い分けは、現在のインスタンスの状態を調べたり、現在のインスタンスに対して処理を行ったりするメソッドはインスタンスメソッドとして宣言するのが普通です。これに対して、そのクラスのインスタンスの中からある特定のインスタンスを見つけ出すメソッドや、クラスフィールドに対して計算や処理を行うメソッドはクラスメソッドとして宣言するのが普通です。

では応用例として、前回の長方形を定義したクラスでインスタンス化された数を知りたい場合どうしたら良いでしょう。
コンストラクタはインスタン化される度に呼びだされます。コンストラクタが呼び出されたときの番号をnumberフィールドに代入します。そのためには、コンストラクタが呼び出される度にカウントした情報を保持するフィールドを宣言する必要があります。counterフィールドを全インスタンスに共通の情報を保持する場所としてクラスフィールドに設定し、クラスフィールドに対して処理を行うクラスメソッドをつかってインスタンス化された回数を調べてみます。

calss Rectangle{
    //クラスフィールド
    //カウンターとしてクラスフィールドcounterを宣言します。
	private static int counter = 0;
    //フィールド
	public int number;

	//コンストラクタ
	public Rectangle(int w,int h){
		this.width = w;
		this.height = h;
			
		number = counter;
		counter++;
		//number = counter++;と記述することもできます。
	}

	//インスタンスをカウントするクラスメソッド
	public static int getCounter(){
		return counter;
	}

	//メインメソッド
	public static void main(String[] args) {
		//クラスメソッドの呼び出し:クラス名.メソッド名(引数)
        //クラスメソッドはインスタンスを作らなくても呼び出すことができます
		System.out.println("カウンターは、" + Rectangle.getCounter());
    }
}