クラス変数とインスタンス変数
職場で「クラス変数とクラスインスタンス変数の違い」が話題にあがっていて、以前理解したよな、と思いつつ咄嗟に整理して述べられないなと思ったので、思い出しつつまとめてみる。
基本的にはクラス変数とインスタンス変数というものがある。
まずサンプルコード。
class Parent @@var = 'class variable of Parent' @var = 'instance variable of Parent (so called class instance variable)' class << self def at_at_var @@var end def at_var @var end end def initialize @var = 'instance variable of parent' end def at_at_var @@var end def at_var @var end end
インスタンス変数とは
あるインスタンスが保持する変数。そのインスタンスにおいて利用できる。@{変数名}
により指示される。
たとえば、parentという「Parentクラスのインスタンス」は@var(='instance variable')
というインスタンス変数をもっている。
parent = Parent.new parent.at_var # => "instance variable of parent"
同様に、Parentという「Classクラスのインスタンス」は@var(='instance variable of Parent (so called class instance variable)')
というインスタンス変数をもっている。
Parent.at_var # => "instance variable of Parent (so called class instance variable)"
後者のように「Classクラスのインスタンス」が持つインスタンス変数のことを「クラスインスタンス変数」と呼ぶことがある。
クラス変数とは
あるクラスが保持する変数。@@{変数名}
により指示される。
当然ながらParentクラスは自身のクラス変数を利用できる。
Parent.at_at_var # => "class variable of Parent"
クラス変数はこれに加えて、以下の特徴をもつ。
1. Parentクラスのインスタンスから、Parentクラスのクラス変数にアクセスできる
parent.at_at_var # => "class variable of Parent"
2. Parentクラスを継承したChildクラスから、継承元であるParentクラスのクラス変数にアクセスできる
class Child < Parent def initialize @var = 'instance variable of child' end end Child.at_at_var # => "class variable of Parent"
3. (上記の合わせ技として)Parenetクラスを継承したChildクラスのインスタンスから、Childクラスの継承元であるParentのクラス変数にアクセスできる
child = Child.new child.at_at_var # => "class variable of Parent"
おまけ
仕組みはこれだけだと思う。最後に念のため、上で述べたクラス変数の「色んなところからアクセスできる性質」は、クラスインスタンス変数には与えられていないことを確認する。
1. Parentクラスのインスタンスから、Parentクラスのクラスインスタンス変数にはアクセスできない
parent.at_var # => "instance variable of parent"
@varはparentのインスタンス変数を指してしまっている。
2. Parentクラスを継承したChildクラスから、継承元であるParentクラスのクラスインスタンス変数にはアクセスできない
Child.at_var # => nil
@varは「ChildというClassクラスのインスタンスが持つインスタンス変数」を指してしまっている。(これは宣言していないのでnil
が返っている。)
3. Parenetクラスを継承したChildクラスのインスタンスから、Childクラスの継承元であるParentのクラスインスタンス変数にはアクセスできない
child.at_var # => "instance variable of child"
@varはchildのインスタンス変数を指してしまっている。
丁寧に言語化すると「ClassクラスのインスタンスであるHogeクラスのクラスインスタンス変数」とか、どうしても早口言葉っぽくなるな...。
以上です。