「クラス変数」の版間の差分

出典: フリー百科事典『ウィキペディア(Wikipedia)』
削除された内容 追加された内容
自己リンクを修正
5行目: 5行目:
[[統一モデリング言語|UML]]ではクラス変数のことを、特別な意味を持つ'''[[属性]]'''として'''クラススコープ'''({{Lang|en|class scope}})と呼ぶ。
[[統一モデリング言語|UML]]ではクラス変数のことを、特別な意味を持つ'''[[属性]]'''として'''クラススコープ'''({{Lang|en|class scope}})と呼ぶ。
== Ruby ==
== Ruby ==
本節では[[スクリプト言語]]である[[Ruby]]で[[クラス変数]]の概略を記す。
本節では[[スクリプト言語]]である[[Ruby]]でクラス変数の概略を記す。


<pre><nowiki>
<pre><nowiki>

2009年3月8日 (日) 12:13時点における版

クラス変数class variable)または、静的メンバ変数static member variable)、静的フィールドstatic field))とは、同一クラス派生クラスで共有される変数である。 そのため、関連クラスに渡って共通に使用できる大域変数(グローバル変数)であるともいえる。 クラス変数はフィールドの一部であるが、インスタンス変数と比べ使われる頻度や重要性が少ないことからインスタンス変数のことだけをフィールドと呼ぶことがある。

UMLではクラス変数のことを、特別な意味を持つ属性としてクラススコープclass scope)と呼ぶ。

Ruby

本節ではスクリプト言語であるRubyでクラス変数の概略を記す。

# Ruby Script
class A
	@@n="Default Value"

	def printClassVariable
		p @@n
	end

	def setClassVariable(var)
		@@n=var
	end
end

class B < A
end

class C < B
end

a = A.new
b = B.new
c = C.new

a.printClassVariable #=> Default Value
b.printClassVariable #=> Default Value
c.printClassVariable #=> Default Value

a.setClassVariable("Value is changed")

a.printClassVariable #=> Value is changed
b.printClassVariable #=> Value is changed
c.printClassVariable #=> Value is changed

Java

本節では、Javaにおけるクラス変数の例を記す。 Javaにおいて、static修飾子を使うことで、クラス変数を宣言できる。 下記の例において、2行目で宣言されているfooはクラス変数であり、3行目で宣言されているvarはインスタンス変数である。 冒頭でも説明されているように、クラス変数は同一クラス派生クラスで共有される。ただし、クラス変数がprivateの場合や、パッケージプライベートで派生クラスがパッケージ外にありそのクラスがパッケージプライベートである場合は、派生クラスから参照することはできない。

class Hoge {
  static int foo; //クラス変数
  int var; //インスタンス変数
}

このHogeクラスを実際に使用する例:

public class Main {
  public static void main(String[] args){
    Hoge.foo = 100; //Hogeクラスのクラス変数に100を代入
    Hoge hoge = new Hoge(); //インスタンスを生成
    hoge.var = 20; // 作成したhogeインスタンスのインスタンス変数varに20を代入
    System.out.println("Hoge.foo = " + Hoge.foo); //fooを表示
    System.out.println("hoge.var = " + hoge.var); //varを表示

    //hogeインスタンスでクラス変数fooを読むこともできる(ただし、推奨されない文法)。
    System.out.println("hoge.foo = " + hoge.foo); 


    hoge.foo = 700; //クラス変数fooに700を代入
    hoge.var = 800; //hogeインスタンスのインスタンス変数varに800を代入

    System.out.println("Hoge.foo = " + Hoge.foo); //Hoge.fooを表示
    System.out.println("hoge.foo = " + hoge.foo); //hoge.fooを表示
    System.out.println("hoge.var = " + hoge.var); //hoge.varを表示

    Hoge another = new Hoge(); //インスタンスをもう一つ生成
    another.foo = 777; //クラス変数fooに777を代入
    another.var = 888; //anotherインスタンスのインスタンス変数varに888を代入

    System.out.println("another.foo = " + another.foo); //fooを表示
    System.out.println("another.var = " + another.var); //varを表示

    System.out.println("Hoge.foo = " + Hoge.foo); //Hoge.fooを表示
    System.out.println("hoge.foo = " + hoge.foo); //fooを表示
    System.out.println("hoge.var = " + hoge.var); //varを表示
   
  }
}

実行結果

Hoge.foo = 100
Hoge.var = 20
hoge.foo = 100
Hoge.foo = 700
hoge.foo = 700
hoge.var = 800
another.foo = 777
another.var = 888
Hoge.foo = 777
hoge.foo = 777
hoge.var = 800

この例ではインスタンス変数との違いを示すためにインスタンス変数varを用意した。 クラス変数Hoge.fooとhoge.fooとanother.fooはすべて同一のものであるためどれかに値を代入するとどれを参照しても代入された値となる。この例ではまずHoge.fooに100を代入した。当然100を出力する。hoge.fooはHoge.fooとクラス変数を参照しているため100を出力する。次にhoge.fooに700を代入する。Hoge.fooもhoge.fooもどちらも700を出力する。次に新たにインスタンスanotherを生成する。another.fooに777を代入しanother.varには888を代入する。このとき、当然another.fooは777、another.varは888を出力する。ただし、Hoge.foo、hoge.fooの値は、Hogeクラスで共有されているクラス変数であるためどちらも777になっている。hoge.varは異なるインスタンスの変数であるため800のままである。

用途

クラス変数はクラスから生成される全てのインスタンスで共有可能な特徴を持つ変数である。この特徴を生かしたクラス変数の代表的な用途は以下の通り。

  1. 定数
    • クラスと関連を持つ定数の定義に使用できる。
      • 処理系の実装にもよるが、通常、クラス変数はクラスがロードされた際にメモリ上に確保され、そのメモリを全てのインスタンスが共有する。よって、メモリ使用量が節約できるメリットがある。
      • 定数であることを明示的に示すため、定数に用いるクラス変数は読み取り専用にすることが望ましい。
  2. クラスの状態の保持
    • あるクラスのインスタンス全てから共有可能な「クラスの状態」を表す変数の定義に使用できる。
      • クラスの状態の保持の代表例として、Singleton パターンでシングルトンオブジェクトを記憶する変数が挙げられる。
        • Singleton パターンでクラス変数を用いる場合、初めて生成されるインスタンスをクラス変数と関連付けて「そのクラスのインスタンスが生成済みである」というクラスの状態を保持する。

関連項目