LoginSignup
0
0

More than 3 years have passed since last update.

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

Posted at

職場で「クラス変数とクラスインスタンス変数の違い」が話題にあがっていて、以前理解したよな、と思いつつ咄嗟に整理して述べられないなと思ったので、思い出しつつまとめてみる。

基本的にはクラス変数とインスタンス変数というものがある。

まずサンプルコード。

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')というインスタンス変数をもっている。
ruby
parent = Parent.new
parent.at_var # => "instance variable of parent"

同様に、Parentという「Classクラスのインスタンス」は@var(='instance variable of Parent (so called class instance variable)')というインスタンス変数をもっている。
ruby
Parent.at_var # => "instance variable of Parent (so called class instance variable)"

後者のように「Classクラスのインスタンス」が持つインスタンス変数のことを「クラスインスタンス変数」と呼ぶことがある。

クラス変数とは

あるクラスが保持する変数。@@{変数名}により指示される。

当然ながらParentクラスは自身のクラス変数を利用できる。
ruby
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クラスのクラスインスタンス変数」とか、どうしても早口言葉っぽくなるな...。

以上です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0