staticクラス(静的クラス)と静的コンストラクタ
拡張メソッドの記事の中で、 拡張メソッドはstaticクラスに実装すると述べた。
では、そのstaticクラスとは何だろうというのが今回のテーマである。
staticクラス
class宣言の前にstaticを付けると、staticクラス(静的クラス)になる。
クラスのメンバーにstaticキーワードを指定すると、インスタンスでは無くクラスに付随するメンバー(クラスメソッド、クラス変数)としてアクセスできる。
これは、javaでもおなじみの事である。
しかし、javaとは異なり、class宣言の前にstaticを指定するとstaticクラスとなり、クラスにstaticなメンバー以外のメンバーを実装できないように強制する事ができる。
staticなメンバー以外のメンバーを持てないという事は、インスタンスを作成しても使い道が無いので、staticクラスではインスタンスを作成する事ができない。
逆に言うと、インスタンスを作成させたくないクラスを定義する場合は、クラスをstaticクラスとして実装する。
staticクラスはシールされる。つまり継承する事はできない。
Mathクラスのように、staticなメンバーだけで構成されるクラスは、staticクラスとして実装するに事になる。
staticクラスは、ある特定の用途向けの定数をまとめて定義したりと、いわゆるHelperクラスを実装するのに適している。
サンプルプログラムが無いのもさみしいので、 以下にstaticクラスの例として、中学生くらいの時に習った昔懐かしい「ピタゴラスの定理」を用いて、2辺がaとbである直角3角形の斜辺の長さを求めるメソッドを実装したMyMathクラスの例を示す。
もう、ピタゴラスの定理なんかとっくに忘れてしまった、という方も多いと思いますが。
Javaには、同等の機能のクラス(staticなメンバー以外のメンバーを実装できないように強制するクラス)は存在しない。
Javaにもclass宣言の前にstaticを指定するクラスが存在するが、これはc#のstaticクラスとはまた別の機能である。
Javaの場合にはクラスのstaticなメンバーとして、classの内部クラスを定義するという意味になるようだ。
静的コンストラクタ
コンストラクタは、通常、クラスのインスタンスが作成する時に呼び出されるが、c#では静的コンストラクタというものも存在する。
静的コンストラクタは、staticクラスに限らずクラスの静的メンバーを初期化する時に使われる。
静的コンストラクタは明示的に呼び出す事ができないので、引数を渡す事はできない。
静的コンストラクタはシステムによって勝手に呼び出されるため、呼び出されるタイミングを知ることはできないが、どうも、プログラムがらクラスが最初にアクセスされるタイミングで呼び出されるようだ。
以下のようなプログラムを使って、静的コンストラクタの実行されるタイミングを調べてみた。
このプログラムの実行結果は以下のようになる。
クラスの定数にアクセスしても、静的コンストラクタは呼び出されないが、readonlyメンバーにアクセスする前には呼び出されている。
クラスの定数のアクセスにコードの実行は必要ないが、クラスのstaticなメンバーの初期化にコードの実行が必要な可能性のあるstaticメンバーにアクセスする前には、静的コンストラクタを実行してstaticメンバーを初期化しておく必要があるという事のようだ。
Javaには静的コンストラクタは存在しないが、 同様の機能としてstaticイニシャライザという機能が存在する。(イニシャライザ(initializer) ― staticイニシャライザとインスタンスイニシャライザ - 愚鈍人を参照)
参考URL