ЯoomeR

プログラミング~実装とエラー解決と、時々、AI~

5分で分かるクラス変数とインスタンス変数

クラスとインスタンスについて

インスタンス変数とは

名前の通り、「インスタンスが持つ変数」のことです。

class Yamada

  def set_skill(power)
    @skill =  power
    p "付与されたスキルは「#{@skill}」です。"
  end
  
end


tarou = Yamada.new
#tarouというインスタンスの作成

jirou = Yamada.new
#jirouというインスタンスの作成

tarou.set_skill("手から炎が出ます")
jirou.set_skill("水を生み出します")

まずはtaroujirouというインスタンスを作成します。

次に、taroujirouに対してそれぞれset_skillというメソッドを行います。

同じメソッドを実行していますが、引数が異なるため、

@skillの中身がtarouとjirouでそれぞれ別の値になっています。

インスタンスごとに値が異なる、これがインスタンス変数です。

インスタンスの特徴まとめ

クラス変数とは

流れで察された方もいらっしゃるかもしれません。

クラス変数は「クラス内で共通の値を持つ変数」です。

まずはこちらをご覧ください。

class Yamada

  def initialize
    @count = 1
    @count = @count +1
    p "@countの値は#{@count}です。"
  end
  
end


tarou = Yamada.new

jirou = Yamada.new

インスタンスが生成されるたびに@countの値を1つずつ増やすことが目的です。

しかし、@countはインスタンス変数であり、それぞれのインスタンスが個別の値を持つために加算することができません。

インスタンスが生成されるたびに@countが新たに定義されるためです。

以下が実行結果です。

"@countの値は2です。"
"@countの値は2です。"

困りましたね。

このように「クラス内で共通の変数を使用したい時」に役立つのがクラス変数です。

今度はクラス変数を使用しましょう。

class Yamada
@@count = 1

  def initialize
    @@count = @@count +1
    p "@countの値は#{@@count}です。"
  end
  
end


tarou = Yamada.new

jirou = Yamada.new

実行結果は以下のとおりです。@@countの値が保持されていることがわかりますね。

"@@countの値は2です。"
"@@countの値は3です。"

クラス変数の特徴まとめ

  • @@が先頭につく
  • クラス内で共通の値を持つことができる
  • クラス内に定義される

インスタンス変数の更新を見てみよう

class Yamada

  def fire
    @quote1 = '手から炎が出ます'
    p @quote1
  end

  def water
    @quote2 = '水を生み出します'
    p @quote2
  end
  
end


tarou = Yamada.new

tarou.fire
tarou.water

この結果が

"手から炎が出ます"
"水を生み出します"

となることは問題ないでしょう。

では、こうしてはどうなるでしょうか?

class Yamada

  def fire
    @quote = '手から炎が出ます'
    p @quote
  end

  def water
    @quote = '水を生み出します'
    p @quote
  end
  
end


tarou = Yamada.new

tarou.fire
tarou.water

この場合も同じ結果となります。

これはdef fireで定義した@quotedef waterで更新されるためです。

"手から炎が出ます"
"水を生み出します"

それでは問題です。

以下の場合はどのように出力されるでしょうか?

class Yamada

  def fire
    @quote = '手から炎が出ます'
    p @quote
  end

  def water
    p @quote
  end
  
end


tarou = Yamada.new

tarou.fire
tarou.water

簡単ですね。

正解は以下です。

"手から炎が出ます"
"手から炎が出ます"

さらに発展問題です。

以下の場合はどうなるでしょうか?

class Yamada

  def fire
    p @quote
  end

  def water
    @quote = '水を生み出します'
    p @quote
  end
  
end


tarou = Yamada.new

tarou.fire
tarou.water

先ほどと同じになるでしょうか?

正解は以下です。

nil
"水を生み出します"

コードは上から読まれるため、def fireの中ではまだ@quoteが定義されていません。

よってnilが出力されます。

まとめ

インスタンスの特徴まとめ

クラス変数の特徴まとめ

  • @@が先頭につく
  • クラス内で共通の値を持つことができる
  • クラス内に定義される