C言語の構造体との違いを知るために、次の正しくないクラスのコードを示します。
public class Record2{//staticだけで、フィールドとメソッドを作る public static String sho; // 商品コード public static short suu; // 数量 //n番目表示としてオペレータ用で画面表示する public static void display(int n){ System.out.printf("%4d番目レコード:\n", n); System.out.printf("\t商品コード:%s\n", sho); System.out.printf("\t数量%d:\n", suu); } }
次に、このクラスを利用して(商品コード、数量)の2件分記憶しようとしている例を示します。
これは、正しく動作しないことを確認するプログラムです。
public class Test { public static void main(String[] arg) { Record2.sho = "A01"; Record2.suu = 10; Record2.display(1); Record2.sho = "A03"; //"A01"が上書きされる Record2.suu = 5; //10が上書きされる Record2.display(1); Record2.display(2); } }
実行結果です。当然ですが、1件目に記憶した内容が上書きされて無くなっています。
>java Test 1番目レコード 商品コード:A03 数量:5 2番目レコード 商品コード:A03 数量:5
public staticが付くフィールドの sho や suu は、クラス名を付けて使えば、グローバル変数のように使えます。
よって、例えば他のクラスのメソッドで Record2.suu = 10; の ように使えるわけです。
このように、staticが付くフィールドは、クラス専用に使う変数なので、クラス変数と呼ばれます。
同様で、public staticが付くメソッドdisplayは、クラス名を付けて使えば、グローバル関数のように使えます。
よって、例えば他のクラスのメソッドで Record2.display(1); の ように使えるわけです。
C言語などで、関連する情報をまとめて管理する場合、構造体を使いました。
じつは、それに対応するものがクラスです。
『商品コードと数量』の構造体に対応するものを、Record2の名前のクラスで作成すると
次のようになります。
(上記に対して、staticが無くなっています。)
public class Record2{ public String sho; // 商品コード public short suu; // 数量 //n番目表示としてオペレータ用で画面表示する public void display(int n){ System.out.printf("%4d番目レコード:\n", n); System.out.printf("\t商品コード:%s\n", sho); System.out.printf("\t数量%d:\n", suu); } }
これによって new Record2() の表記で、Record2クラスのオブジェクトが生成されます。 そのオブジェクトを、変数a、bに管理し、 それぞれの sho と suu フィールドの 記憶域ができ、そのオブジェクトに対してdisplayメソッドの実行ができるようになります。以下に、その例を示します。
public class Test { public static void main(String[] arg) { Record2 a = new Record2(); Record2 b = new Record2(); a.sho = "A01";//1件目 a.suu = 10; b.sho = "A03";//2件目 b.suu = 8; a.display(1);//1件目表示 (オブジェクトaで、実行) b.display(2);//2件目表示 (オブジェクトbで、実行) } }
この実行結果を以下に示します。
Z:\Java>java Test 1番目レコード 商品コード:A01 数量:10 2番目レコード 商品コード:A03 数量:8 Z:\Java>
このページ先頭で示した正しくないRecord2クラスです。
public class Record2{//staticだけで、フィールドとメソッドを作る public static String sho; // 商品コード public static short suu; // 数量 //n番目表示としてオペレータ用で画面表示する public static void display(int n){ System.out.printf("%4d番目レコード:\n", n); System.out.printf("\t商品コード:%s\n", sho); System.out.printf("\t数量%d:\n", suu); } }
このクラスをnew するとどうなるのでしょうか? コード例を以下に示します。
Record2 a = new Record2();
Record2 b = new Record2();
このような生成も可能ですが、Record2の各フィールドがstaticなので
実質的に各オブジェクトとして記憶可能なフィールドはありません。
ですが、次のような表現が可能です。
b.sho = "B01";
b.suu = 20;
a.display(1);
各フィールドがstaticなので、オブジェクト共通とも言える記憶(クラス変数)域更の変更です。
よってbに記憶したのに、aでも表示できていまいます。
1番目レコード:
商品コード:B01
数量20:
つまり上記は、以下のようにクラスRecord2を指定した表現の次と同じなのです。
Record2.sho = "B01";
Record2.suu = 20;
Record2.display(1);
このようにstaticのフィールドやメソッドをアクセスする場合は、クラス名を指定して使った方が分かりやすい表現でしょう。
後発のプログラミング言語でC#と呼ばれるものがありますが、C#では、staticメンバを、オブジェクトの変数でアクセスできない仕様になっています。
個人的もオブジェクト変数を指定して、staticのメンバをアクセスしないようにしています。
以降において、クラスの外からstaticのメンバを指定する場合は、必ずクラス名を指定する表現で示します。