Singleton Method <> 是「百獸海賊團」!碰上四皇凱多有勝算嗎?

https://ithelp.ithome.com.tw/upload/images/20201006/20128363CAkf2qfYdC.jpg

[Day28] 今天登場的是媲美侏羅紀公園的百獸海賊團!幹部三災個個雄壯威武,船長凱多更被譽為海賊王世界最強生物!

今日圖已端上,那麼話不多說
這篇要介紹的是:單體方法(Singleton Method)


什麼是單體方法

第一次聽到 singleton 這個詞是在泰安老師的課上,記得那個時候一邊聽一邊心裡卻在吶喊著:「奇怪明明就是說中文啊···為什麼我有聽沒有懂···」(狀態表示為三觀盡毀)

直到現在才比較明白了,簡單來說,單體方法是一種專屬於某個物件的方法,

1
2
3
4
5
6
7
8
9
10
11
12
13
class Cat
# ...
end

meme = Cat.new
didi = Cat.new

def meme.feet # singleton method
puts "有穿白襪"
end

meme.feet # => 有穿白襪
didi.feet # => NoMethodError (undefined method `feet' for #<Cat:0x00007fd2359aa790>)

可以看到這邊定義的 feet 方法只能給 meme 這個實體物件使用,而其他的實體物件,就算是同一類別產生的實體,都無法使用 feet 方法,

由此可知,我們可以在任意物件上定義單體方法,不過前提是要先有那個物件存在,不然就會看到噴錯:

1
2
3
4
5
6
7
8
9
10
11
class Cat
# ...
end

def meme.feet # singleton method
puts "有穿白襪"
end

meme = Cat.new

meme.feet # => NameError (undefined local variable or method `meme' for main:Object)

看起來好像跟類別方法有點像?

沒錯!類別方法其實也是一種單體方法,之前介紹到類別方法時,會這樣寫:

1
2
3
4
5
6
7
class Crew
def self.all
puts "全員到齊"
end
end

Crew.all # => "全員到齊"

在這裡,我們可以把 self 換成這個類別 Crew (昨天有提到 self 指向目前正在執行的物件),所以這樣寫也是可以的:

1
2
3
4
5
6
7
class Crew
def Crew.all
puts "全員到齊"
end
end

Crew.all # => "全員到齊"

又或者這樣,在類別裡執行類別方法也是可以的:

1
2
3
4
5
6
7
8
9
10
class Crew
def Crew.all
puts "全員到齊"
end

all
end

# 印出
全員到齊

單體方法被定義在哪裡?

在一開始的例子裡,我看到 meme 可以呼叫我自己定義的 feet 方法,但仍然有些不解,為什麼這個方法被定義在類別的外面,卻又只能給特定的實體取用呢?

我們先看一般的方法定義:

1
2
3
4
5
6
7
8
9
10
11
def eat
"肚子餓了就要吃東西"
end

class Cat
end

meme = Cat.new

meme.eat # => "肚子餓了就要吃東西"
didi.eat # => "肚子餓了就要吃東西"

嗯···明顯不一樣,揪竟單體方法是被定義在哪裡呢?
meme.feet 又做了什麼呢?


今天到這邊先告個段落,要理解艱澀的概念,我們必須得休息一會喝個水然後睡個覺,明天會來繼續討論 singleton class 這個主題!