實體變數 <> 一流強者都要會的武裝色霸氣

[Day21] 運用武裝色霸氣就能在皮膚表面覆蓋一層堅硬的盔甲,同時提升防禦力和攻擊力!

嗨大家好!今晚想來點「實體變數」~

到目前為止我們所提的變數都是區域變數,而一開始介紹變數時為什麼沒有講到這部分呢?(根本就是忘了)

不過我覺得一旦理解 scope 的概念後,自然而然地就能了解區域變數為什麼叫做「區域」變數了:因為它只能在某個 scope 內生效。

如果有點失憶的朋友可以回到 鐵人賽第 4 天


Ruby 裡有哪些變數?

共分成以下幾種:

類型 範例 預設值 說明
區域變數 name 作用範圍僅限在一個區域裡,方法內外不可相互取用。
實體變數 @name nil 在類別中可以被各個方法取用,也可以成為實體物件的屬性,但不同實體物件的屬性不一定相同,
類別變數 @@name 同一類別建立的實體物件都可以取用,類別不同就無法。
全域變數 $name nil 可以在不同的類別被取用。
常數 Name nil 主要用於類別與常數的命名。

雖然變數有這麼多種,不過由於在實務上很少用到類別變數和全域變數,相對我也沒這麼熟悉,因此這篇將會聚焦介紹 Ruby 的實體變數。


實體變數是什麼?

在 Ruby 裡,我們會在變數的名字前面加一個 @ ,來代表實體變數,也可以當作實體物件的屬性(attribute)。

來看一下定義:

實體變數的 scope 是整個類別,因此它能夠在同一類別的方法之間傳遞,而每一個物件的屬性會各別賦值,不會和其他的物件共享,它會隨著不同的物件而有不同的值。

上面這段文字似乎太抽象了,直接看 code 吧:

1
2
3
4
5
class Cat
def name
@name
end
end

好像還不太夠,再加上 initialize 試試看:

1
2
3
4
5
6
7
8
9
10
class Cat
def initialize(name, color)
@name = name
@color = color
end

def color
"#{@name}是隻#{@color}色的小貓"
end
end

如此一來,我們就可以在 Cat 類別產生新實體的那一刻,自動把參數指定給實體變數,變成專屬於這個實體的屬性,而不會與其他實體共享。

我們來養一隻小貓:

1
2
3
4
5
miru = Cat.new("miru","虎斑")
puts miru.color

# 印出
miru是隻虎斑色的小貓

一隻貓不夠吸,養貓就要養兩隻:

1
2
3
4
5
nini = Cat.new("nini","黑")
puts nini.color

# 印出
nini是隻黑色的小貓

可以看到雖然 mirunini 都使用了同樣的實體變數 @name@color ,但這兩個實體物件各自有屬於自己的屬性,同時,在類別內的實體方法要取用 @name@color 時,也不用再定義這個需要參數。


如果要在類別外取得實體變數?

剛剛有提到,實體變數的 scope 是在整個類別內,不過一旦離開了類別,這個實體變數就不能用了。

因此,如果要在類別外取得這個實體變數,可以這樣做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Dog
class Cat
def initialize(name, color)
@name = name
@color = color
end

def color
"#{@name}是隻#{@color}色的小貓"
end

# getter
def color
@color
end

# setter
def color=(new_color)
@color = new_color
end
end

通常會定義一個同名方法來獲得實體變數的值,這個行為被稱作 getter
而用這個同名方法加上 = 作為另一個方法來重新傳參數給實體變數,這個行為就叫做 setter

1
2
3
4
5
6
7
8
9
10
11
12
didi = Cat.new("didi","橘")
puts didi.color

#印出


# 重新定義值
didi.color= "橘帶一點黃"
puts didi.color

#印出
橘帶一點黃

看到了嗎?我們可以更精準地定義 didi 的顏色啦!


今天就先介紹到這邊啦!關於 gettersetter 的使用方式,明天還會再看到它們!