« Minecraft MODで出来る事 | トップページ | Minecraft MOD開発 11 »

2014年3月20日 (木)

クラス変数とインスタンス変数

2チャンネルでの議論を読んで、少し調べてみた。

class MyClass
{
 public static int a;
 public int b;
}

と定義したとする。

aはクラス変数であり、プログラム起動時(より正確にはクラスローダに読み込まれたとき)に1つだけ作られる。パッケージをimportさえしておけば、どこからでもMyClass.aで読み書きできる。1つしかないので、あちらで書き換えればこちらで読み出すときの値も変わる。

bはインスタンス変数であり、newしたときに作られる。

MyClass my1 = new MyClass();
MyClass my2 = new MyClass();

とすれば、my1.bとmy2.bは別の値を持つ。my1.bを書き換えてもmy2.bには影響しない。まずインスタンスにアクセスできないと、その中のインスタンス変数にアクセスできない。インスタンスが分からないままインスタンス変数にアクセスしようとすると、NullPointerExceptionになる。

クラス変数の存在を許していいのかなぁ? クラス変数をprivateにしてgetter, setterを作るとかそういう話ではない。いくつインスタンス化されたかを数えるカウンタがクラス変数の利用例として挙げられているが、そんなものはインスタンス化する側がList.sizeで管理するものじゃないのか。

MyClassA a;
MyClassB b;
と定義する場合、インスタンスaとbは直接通信できない。
MyClassA a1;
MyClassA a2;
なら定義位置がどれだけ離れていても、クラス変数を介して通信できる。
MyClassA a;
MyClassB b;
としても、MyClassAとMyClassBが共通の親クラスから派生していれば、親クラスのクラス変数を介して通信できる。あれ、できないのかな?

caller⇔calleeとか、制御ループとか、superclass⇔subclassとか、インスタンスのhas-a関係とかの親子関係は子が兄弟同士で直接通信できないことが重要じゃないのか。それを構造化とか隠蔽と呼ぶと思うんだけど。

クラス変数はfinal修飾子を付けて定数のように扱うか、せめてsingletonにすべき。getter/setterを作ればよいという問題じゃない。

« Minecraft MODで出来る事 | トップページ | Minecraft MOD開発 11 »

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1499066/55449978

この記事へのトラックバック一覧です: クラス変数とインスタンス変数:

« Minecraft MODで出来る事 | トップページ | Minecraft MOD開発 11 »