程式扎記: [ Ruby Gossip ] Basic : 模組 - 再看 self

標籤

2014年11月20日 星期四

[ Ruby Gossip ] Basic : 模組 - 再看 self

Source From Here 
Preface 
在 關於 self 中,討論過不同環境中,self 代表的物件,在學到模組之後,再來看看 self 於模組中不同區域的意涵。 

再看 self 
先前說過類別是物件,每個被定義的類別都是 Class 的實例,實際上模組也是物件,每個被定義的模組都是 Module 的實例: 
>> module M1; end
=> nil
>> M1.class
=> Module

實際上,Class 的父類別是 Module,而 Module 則是 Class 的實例,那是先有 Module 還是先有 Class?這感覺好像是雞生蛋或蛋生雞的問題: 
>> Class.superclass
=> Module
>> Module.class
=> Class
>> Class.superclass.class
=> Class
>> Class.superclass.class.superclass
=> Module
>> Class.superclass.class.superclass.class
=> Class
>> Class.superclass.class.superclass.class.superclass
=> Module

因為 Class 與 Module 是以 C 撰寫,類似地,Class 也是類別,Class 本身就是 Class 的實例化。Class 的父類別是 Module,類別可以實例化,但模組不能實例化,除此之外,類別中可以定義的東西,模組中幾乎都可以定義。例如定義模組的模組方法: 
 

在模組本體中,self 代表模組本身,因此若要定義模組方法,可以用 self 取代實際模組名稱,在模組方法中,self 也是代表模組本身,因此模組方法就是屬於模組,類別 include 模組後,無法使用模組方法. 證明如下: 
 

這跟類別中定義類別方法,而子類別繼承後可以直接使用類別方法有點不同: 
 

子類別可以呼叫父類別中定義的類別方法,若是以父類別呼叫類別方法,則 self 代表父類別,若是以子類別呼叫類別方法,則 self 代表子類別。 

如果模組中定義實例方法,由於模組無法實例化,因此被定義的實例方法,一定得被 include 至類別,利用該類別實例化後才能呼叫。例如: 
 

可以看到,模組中定義實例方法時,self 並不代表任何物件,只有在被 include 至類別並實例化後,self 代表的物件,就是被實例化的物件。一個可能會被誤會的是,如果程式區塊中撰寫 self,那 self 代表誰呢?不是程式區塊右邊的訊息接收者,而是看程式區塊外 self 代表誰。例如: 

沒有留言:

張貼留言

網誌存檔