類別變數顧名思義是能夠在類別裡被定義的變數,寫法是 @@
為開頭。
以目前為止的學習經驗中,使用到類別變數的時機非常少,因此接下來的介紹會著重在實體變數。
在 Ruby 裡的實體變數是前面加一個 @
為開頭,這個變數代表實體其獨特的屬性( attribute )。
因為實體變數的 scope
橫跨了整個類別,所以它能夠在同一類別的方法之間傳遞,如果利用 initialize
的特性,當新的實體被 new
出來時,便自動執行一次,把參數傳進類別並指定給實體變數,因此就變成了該實體獨一無二的屬性,不會與其他實體共享。
class Dog
def initialize(color = "黑", age = 2)
@color = color
@age = age
end
def introduction
"這是一隻#{ @color }色的小狗,牠現在#{ @age }個月大了!"
end
end
husky = Dog.new( "灰", 8 )
puts husky.introduction # 印出 這是一隻灰色的小狗,牠現在8個月大了!
shiba_inu = Dog.new( "棕", 13 )
puts shiba_inu.introduction # 印出 這是一隻棕色的小狗,牠現在13個月大了!
puppy = Dog.new
puts puppy.introduction # 印出 這是一隻黑色的小狗,牠現在2個月大了!
剛剛提到實體變數的 scope
橫跨了整個類別,這也代表一旦離開類別就失效了,那如果我真的很想要在類別外取得這個屬性,甚至指定新的屬性給該變數呢?這裡必須定義同名的方法來獲得實體變數的值,再利用同名方法加上 =
作為另一個方法來重新傳參數給實體變數。
class Dog
def initialize(color = "黑", age = 2)
@color = color
@age = age
end
def introduction
"這是一隻#{ @color }色的小狗,牠現在#{ @age }個月大了!"
end
# getter
def color
@color
end
# setter
def color= (new_color)
@color = new_color
end
end
husky = Dog.new( "灰", 8 )
puts husky.color #印出 灰
husky.color = "紅"
puts husky.color #印出 紅
這種手法因為很常使用,所以已經內建了三個方法了:attr_reader
, attr_writer
以 及attr_accessor
,以上述例子來說, attr_reader 等同於 getter
, attr_writer 等同於setter
, attr_accessor 則等同於前兩者,我們改寫如下,可以省掉很多程式碼。
class Dog
attr_accessor :color, :age
def initialize(color = "黑", age = 2)
@color = color
@age = age
end
def introduction
"這是一隻#{ @color }色的小狗,牠現在#{ @age }個月大了!"
end
end
此文同步刊登於CJ-Han的網站