在寫這篇文章前,自認如果今天面試被問到這題,預期腦袋裡會一片空白,只知道這兩個物件都長得非常像但說不出哪裡不同。
google一下,看到最多次的一句話:
Module is similar to a class but it cannot be "inheritance" and "instantiated".
咦?那結論都寫在這了,那是不是不用寫文章了(撒花)?
想了想還是認份的整理一下好了...總要自己驗證一下
開啟irb
可以看到Class背後的老爸竟然就是Module本人啊啊啊啊啊~
(腦袋莫名冒出鍾楚雄...)
那既然類別class是模組Module繼承來的,那代表class有的,Module一定都有,但Module有的,class不一定都有,聽起來很像繞口令,來驗證一下看看哪裡不同。
Module與class的關係看起來就像這樣,要找出差異,我想小學數學有教過,一個大圓包含一個小圓,如果要找出他們不同的地方,只要大圓減去小圓即可。
#irb
2.6.3 :012 > Class.methods - Module.methods
=> []
Module與class的類別方法互相減去,得到的是一個空陣列,代表他們在類別方並沒有差別,再來看實體方法:
#irb
2.6.3 :013 > Class.instance_methods - Module.instance_methods
=> [:allocate, :new, :superclass]
其中allocate
與new
是跟產生實體有關係,superclass
是與繼承有關係,所以可以看得出來:
備註:關於allocate
與new
class Cat
attr_accessor :name
def initialize
@name = "NoName"
end
end
cat1 = Cat.new
p cat1.name # => "NoName"
cat2 = Cat.allocate
p cat2.name # => nil
allocate和new的差別在於:
allocate不會用initialize的方法並回傳實體變數,而new會。
給大家一個例子想像一下:
湘北高校籃球社的同學們突然覺得打籃球打贏山王工業就滿足了,於是就約了烏野高校排球社的同學去打排球。
因為櫻木跟大猩猩等人都沒打過排球,所以為了要讓球打得起來,必須把小不點的打排球技能學起來,那我們可以用哪種方式?
直接寫舉球、托球...等等的技能類別,然後叫湘北類別去繼承他
問題:這樣設計就很像「為了想打"一場"排球就轉學去烏野高校」的感覺...幹嘛為了打排球就轉學啊?
直接寫舉球、托球方法到湘北類別裡面
問題:這樣寫似乎也沒不行,但如果今天山王工業的人突然也想加入打排球,
那不又要再山王工業的類別裡加入舉球、托球方法...
==這時候就是用Module的時機了==
module VolleyTeam
def set
puts '舉球'
end
def toss
puts '托球'
end
end
class BasketTeam
include VolleyTeam #將module include到類別裡
def pass
puts '接球後,傳球!'
end
def shoot
puts '接球後,投籃!'
end
def dribble
puts '運球'
end
end
sakuragi = BasketTeam.new
sakuragi.pass # => 接球後,傳球!
sakuragi.set # => 舉球!
sakuragi.toss # => 托球!
之後如果山王工業真的要加入的話:
class MountainKing
include VolleyTeam
end
他們就也可以一起加入打排球了
上面例子可以做出一個小總結,如果今天要做的功能(method)在很多類別都會用到的話,就可以都抽出來寫在module裡面,再把它include到類別裡使用,跟Rails裡的Partial render有幾分相似概念。
講了那麼多範(幹)例(話),其實類別(Class)與模組(Module)的主要差異就一句話:
==模組(Module)不可繼承、不可實體化==
比較 | 模組(module) | 類別(class) |
---|---|---|
繼承inheritance | ✕ | ✔ |
可實體化instantiation | ✕ | ✔ |
參考資料:
vikingcodeschool
ruby-doc.org
Modules in Ruby: Part I
Difference between a class and a module
Ruby 語法放大鏡
為自己學Ruby on Rails
“Inside of a ring or out, ain’t nothing wrong with going down. It’s staying down that’s wrong.”
— Muhammad Ali, Boxer
本文同步發佈於: https://louiswuyj.tw/
那既然類別class是模組Module繼承來的,那代表class有的,Module一定都有,但Module有的,class不一定都有
==模組(Module)比類別(Class)多了「產生實體」與「繼承」的功能==
==模組(Module)不可繼承、不可實體化==
你搞得我好亂啊!