【Java】staticを指定するクラスメンバと指定しないインスタンスメンバの違い

■クラスメンバ

クラス内でstaticを指定したフィールドやメソッドは、クラスの所有物となり、クラスメンバと呼ぶ。
クラスメンバの書き方、呼び出し方を以下に示す。
書き方としては、メンバ変数宣言およびメソッド作成時、「static」を記載する。
呼び出し方は、作成したクラス名.メソッド名で呼び出す。

▼メンバ変数とクラスメソッドの書き方

class クラス名{
    // メンバ変数
    private static 変数名;

    // クラスメソッド
    public static メソッド名(){
        ここに処理を書く
    }
}

▼作成したクラスメンバの呼び出し方

public class メインクラス名 {
    	public static void main(String[] args) {
            // クラスメンバの呼び出し
            クラス名.メソッド名()
    }
}

■インスタンスメンバ

クラス内でstaticを指定しないフィールドやメソッドは、インスタンスの所有物となり、インスタンスメンバと呼ぶ。
インスタンスメンバの書き方、呼び出し方を以下に示す。
書き方としては、メンバ変数宣言およびメソッド作成時、「static」を記載しない。
呼び出し方は、作成したクラスに対して、インスタンスを行い、インスタンス名.メソッド名で呼び出す。

▼メンバ変数とインスタンスメソッドの書き方

class クラス名{
    // メンバ変数
    private 変数名;

    // インスタンスメソッド
    public  メソッド名(){
        ここに処理を書く
    }
}

▼作成したクラスメンバの呼び出し方

public class メインクラス名 {
    	public static void main(String[] args) {
            // クラスのインスタンス
            クラス名 インスタンス名 = new クラス名

            // インスタンスメンバの呼び出し
            インスタンス名.メソッド名()
    }
}

■今回作成するプログラムの仕様

今回は、人の名前・番号をもとに挨拶を出力するプログラムを作成する。

▼処理内容

・メッセージを出力するクラス

▼メンバ変数
人の名前(インスタンスメンバ)
メッセージ番号(インスタンスメンバ)
カウンタ(クラスメンバ)

▼コンストラクタ
人の名前を設定
メッセージ番号を設定
インスタンスを生成する度にカウンタをインクリメント

▼メッセージ出力インスタンスメソッド(引数:人の名前、メッセージ番号)
メッセージ番号が0の場合は日本語で挨拶を出力する。
メッセージ番号が1の場合は英語で挨拶を出力する。
メッセージ番号が0および1以外の場合は入力値が異なることを出力する。

▼カウンタ数を表示するクラスメソッド
インスタンスを生成する回数を出力する。

・メインクラス

[1回目]メッセージを出力するクラスのインスタンス(引数:”太郎”, 0)
メッセージ出力インスタンスメソッドを呼び出す。
カウンタ数を表示するクラスメソッドを呼び出す。
[2回目]メッセージを出力するクラスのインスタンス(引数:”Mike”, 1)
メッセージ出力インスタンスメソッドを呼び出す。
カウンタ数を表示するクラスメソッドを呼び出す。
[3回目]メッセージを出力するクラスのインスタンス(引数:”NG”, 2)
メッセージ出力インスタンスメソッドを呼び出す。
カウンタ数を表示するクラスメソッドを呼び出す。

■サンプルコード

// メッセージを出力するクラス
class OutputMessage {
	// メンバ変数
	private String person_name;			// 人の名前(インスタンスメンバ)
	private int msg_num;				// メッセージ番号(インスタンスメンバ)
	private static int count_num = 0;	// カウンタ(クラスメンバ)
	
	// コンストラクタ
	public OutputMessage(String name, int num) {
		this.person_name = name;
		this.msg_num = num;
		// インスタンスする度にインクリメント
		OutputMessage.count_num ++;
		
	}
	
	// メッセージ出力インスタンスメソッド
	public void ShowMsg() {
		// メッセージ番号が0の場合は日本語
		if(msg_num == 0){
			System.out.println("こんにちは" + person_name);
		// メッセージ番号が1の場合は英語
		} else if(msg_num == 1) {
			System.out.println("Hello" + person_name);
		} else {
			System.out.println("メッセージ番号は0か1を入力してください");
			System.out.println("入力値:" + msg_num);
		}
		
	}
	
	// カウンタ数を表示するクラスメソッド
	public static void ShowInstanceCount() {
		System.out.println(OutputMessage.count_num + "回クラスが呼び出されました");
	}
	
}


public class Sample {
	public static void main(String[] args) {
		// メッセージを出力するクラスのインスタンス(1回目)
		OutputMessage Jmsg = new OutputMessage("太郎", 0);
		
		// インスタンスメンバの呼び出し
		Jmsg.ShowMsg();
		
		// クラスメンバの呼び出し
		OutputMessage.ShowInstanceCount();
		
		// 区切り
		System.out.println("####################");
		
		// メッセージを出力するクラスのインスタンス(2回目)
		OutputMessage Emsg = new OutputMessage("Mike", 1);
		
		// インスタンスメンバの呼び出し
		Emsg.ShowMsg();
		
		// クラスメンバの呼び出し
		OutputMessage.ShowInstanceCount();
		
		// 区切り
		System.out.println("####################");
		
		// メッセージを出力するクラスのインスタンス(3回目)
		OutputMessage NGmsg = new OutputMessage("NG", 2);
		
		// インスタンスメンバの呼び出し
		NGmsg.ShowMsg();
		
		// クラスメンバの呼び出し
		OutputMessage.ShowInstanceCount();
	}
	
}

■実行結果

こんにちは太郎
1回インスタンスを生成しました
####################
HelloMike
2回インスタンスを生成しました
####################
メッセージ番号は0か1を入力してください
入力値:2
3回インスタンスを生成しました

▼補足説明

同じクラスを複数生成した場合、クラスメンバは、メモリ上に一つだけ存在し、全てのインスタンスから共有される。
一方、インスタンスメンバはメモリ上にインスタンス数だけ存在し、それぞれのインスタンスが所有する。
インスタンスする度にインクリメントするカウンタ番号は、クラスメンバがメモリ上に一つだけ存在する性質を利用しているため、インスタンスを生成する回数を保持することが可能である。

コメント