接續上一篇類別(Class), 這篇來説說模組(Module)吧!
Module
Module 的起手式:
module Skill03
def surf
# do something
end
end
如果還記得 Class 的起手式,會發現,寫起來好像一樣 @@?
Module & Class
為了先切割兩者,就先來看看到底 Module & Class 什麼關係? 有什麼差別?
Class.superclass
=> Module
在 irb 試著輸入這樣,你會發現 Class
的上層是 Module
。
那差別呢?
Class.instance_method - Mudule.instance_method
=> [:allocate, :superclass, :new]
Ruby 告訴我們,Class
比 Module
多三個方法,正因為這樣所以 Module
不能 new
新實體、無法繼承。(好奇 allocate
,可以看看[這篇][Ruby allocate
method])
How to Use Module?
初步認識 Module & Class 關聯與差別,接著來看看怎麼使用:
module Skill03
def surf
puts "Aloha"
end
end
class Pikachu
include Skill03
end
pikachu = Pikachu.new
pikachu.surf
=> Aloha
在 Pikachu
類別中使用 include
就能將 Skill03
模組加入,而一個新的 Pikachu
實體就能使用模組裡的衝浪了。
有趣的地方是,模組可以在不同類別間使用。假設我想讓柯P可達鴨學會衝浪可以這樣做:
class Psyduck
include Skill03
end
kp = Psyduck.new
kp.surf
=> Aloha
include
, extend
?
剛剛用 include
讓想學衝浪的皮卡丘跟可達鴨都學會了,然後你會發現 surf
的作用對象都是實體(instance):pikachu
, kp
。換句話說,使用 include
會讓衝浪變成是實體方法(instance method)。
Pikachu.surf
Psyduck.surf
=> NoMethodError
相對地,使用 extend
可以使衝浪變成是類別方法(class method),同樣的無法作用於實體(instance)。(關於實體方法與類別方法,剛好在 Class 有稍稍提到。)
class Psyduck
extend Skill03
end
Psyduck.surf
=> Aloha
kp.surf
=> NoMethodError
When to Use?
如果有玩過掌上型遊戲機(GameBoy)的神奇寶貝,那應該知道衝浪是需要透過招式機學會的。是的,模組就像是招式機,只要 include
,連電氣系的皮卡丘都可以衝浪。無法因為是水系神奇寶貝就能繼承衝浪。
不適用類別繼承的原因大概就像皮卡丘不用為了會衝浪而轉系當水系神奇寶貝吧。(這樣就不能使出招牌十萬伏特了…QQ)