程式扎記: [ Ruby Gossip ] Advance : 類別 - 關於 Class

標籤

2014年11月24日 星期一

[ Ruby Gossip ] Advance : 類別 - 關於 Class

Source From Here
Preface
在 Ruby 中定義的類別,為 Class 的實例。例如:
>> class Some; end
=> nil
>> Some.class
=> Class

如果你如下定義類別:
  1. class Some  
  2.     def some  
  3.         puts "some"  
  4.     end  
  5. end  
也可以如下定義相同功能的類別:


關於 Class
Class.new 時指定的程式區塊是類別定義的本體,程式區塊可以指定程式區塊參數,會傳入建構的 Class 實例,也就是類別定義本身,在程式區塊中使用 self 也可以取得 Class 實例。
>> Class.new { |clz| puts clz; puts self}
#
#
=> #

如果 Class.new 時指定常數作為名稱,那麼常數名稱就會作為類別名稱,如果沒有指定常數作為名稱,那麼就會成為匿名類別(Anonymous class)。例如:


上例中,類別若具有名稱,則會直接顯示名稱,如果是匿名類別,則會顯示實例的十六進位位址表示,在範例中也可以看到,有無指定常數作為名稱,會改變 to_s 的實作。Class.new 時如果沒有指定方法參數,預設就是繼承 Object,可以指定想要繼承的父類別。例如:


類別是 Class 的實例,Class 的實例方法,其實也就是類別的類別方法。例如,雖然不建議改變核心類別實作,但確實是可以在 Class 中定義實例方法,該實作方法將成為所有類別(包括匿名單例類別)都具有的類別方法。例如:


以上只是示範,實際上如果你想某些類別想共同擁有的類別方法,可以抽離至模組中,再讓類別用包括模組的方式來達到目的Class 的存在,開啟了其它定義類別的方式,而不一定要用 class 關鍵字。例如也許你會想要動態地建立類別,名稱可以由使用者輸入:
  1. class Some; end  
  2.   
  3. ARGV.each do |clz_name|  
  4.     Object.const_set(clz_name, Class.new(Some))  
  5. end  
  6.   
  7. ARGV.each do |clz_name|  
  8.     puts Object.const_get(clz_name).new  
  9. end  
如果如下輸入,可以從命令列指定類別名稱並建構實例:
> ruby main.rb A B C D E
#
#
#
#
#

先前談過單例方法與匿名單例類別,其實你也可以想像,Ruby 每建立一個物件前,都會先用 Class.new 建立一個匿名類別,再用該匿名類別建立物件,你定義單例方法時,就是定義在該匿名類別上,而 class << object 的寫法,開啟的也就是該匿名類別,因此可擁有物件個體性的功能存在。

Supplement
Class.inherited(subclass)
Callback invoked whenever a subclass of the current class is created.

Module.const_set(sym, obj) → obj
Sets the named constant to the given object, returning that object. Creates a new constant if no constant with the given name previously existed.

Module.const_get(sym, inherit=true) → obj
Checks for a constant with the given name in mod If inherit is set, the lookup will also search the ancestors (and Object if mod is a Module.)


沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!