【Ruby入門】Rubyのインスタンス変数とクラス変数
Rubyのクラスにおける、インスタンス変数とクラス変数について説明します。
インスタンス変数とクラス変数の違い
インスタンス変数とクラス変数の最も大きな違いは、インスタンス毎に値が固有であるか否かにあります。
具体的のは、以下のようになります。
- インスタンス毎に値が固有:インスタンス変数
- インスタンス毎に値が共通:クラス変数
次から、インスタンス変数とクラス変数について、それぞれ説明していきます。
インスタンス変数とは
インスタンス変数に値を保存しておけば、そのインスタンスごとに固有の値を保持することができます。
インスタンス変数の定義
クラスの中でインスタンス変数を定義するには、「@」のあとに、通常の変数と同じ命名規則で変数を定義します。
class クラス名
def メソッド名
@name = 値
end
end
インスタンス変数へのアクセス
インスタンス変数には、オブジェクトの外から直接アクセスすることはできません。そのため、インスタンス変数にアクセスするためのメソッド(アクセサー)をクラスに定義する必要があります。
たとえば、車についての情報を管理する「Car」というクラスを作り、インスタンスごとに別々の「車名」を管理しておきたい場合、次のようにインスタンス変数「@name」を定義します。
class Car
#インスタンス変数@nameに値をセットする
def setName(str)
@name = str
end
#インスタンス変数@nameを表示する
def dispName
puts @name
end
end
car1 = Car.new
car1.setName("Legacy")
car2 = Car.new
car2.setName("XV")
car1.dispName #=> Legacy
car2.dispName #=> XV
Carクラスからインスタンスを作成し、setNameメソッドでインスタンス変数@nameに名前を代入し、dispNameメソッドで名前を表示します。
重要なのは、インスタンス変数はインスタンスごとに別の値を持っているという点です。
attr_accessorを使ったインスタンス変数
上記の例では、アクセサーをクラスに定義していますが、単純なアクセサーであればattr_accessorを使うことで自動的に定義することができます。
class Car attr_accessor :name end car1 = Car.new car1.name = "Legacy" puts car1.name
書式は以下のような形で、複数のインスタンス変数を定義する場合は、カンマ「,」で区切ります。
class クラス名 attr_accessor :変数名1, :変数名2 end
また、読み込み専用のattr_readerや書き込み専用のattr_writerなどもあります。
クラス変数とは
インスタンス変数がインスタンスごとに固有の値を保持するのに対し、クラス変数はそのクラスと継承をしたサブクラス、インスタンスで共有できる変数です。
クラス変数の定義
クラス変数は、@@から始まる英数字またはアンダースコアで以下のように書きます。
class クラス名 @@name = 値 end
「@@name」に格納した値は、このクラスから生成したインスタンスのすべてで共有されます。ただし、この変数を読み書きできるのは、基本的に、自分のクラスとサブクラスのクラス定義、クラスメソッド、インスタンスメソッドからのみです。
クラス変数の使い方
それでは、クラス変数はどのように使えばいいのでしょうか? 実例を挙げてみましょう。
class Car
@@engine = "gasoline"
def dispCarEngine
puts @@engine
end
end
class LightCar < Car
def changeEngine
##クラス変数をgasolineからelectricに変更
@@engine = "electric"
end
def dispLightCarEngine
puts @@engine
end
end
s1 = LightCar.new
s1.changeEngine
s1.dispLightCarEngine #=> electric
s2 = Car.new
s2.dispCarEngine #=> electric
クラス変数として@@engineを持つCarクラスとCarクラスを継承したLightCarクラスがあります。
LightCarのインスタンスs1が、クラス変数@@engineを変更するchangeEngineメソッドを実行することで、Carクラスのs2のdispCarEngineメソッドの結果もgasolineからelectricになっています。