ruby中的物件是類生成的,而類本身也是物件。ruby的頂級類是object其餘所有的類都直接或簡介繼承與object。其中class繼承module,module繼承object,而所有的物件其實都是class類的示例,這其中當然包括object,module,以及class類本身。這便產生了一些很有趣的事情,這些等下在慢慢道來。這裡先說說ruby內部實現中的一些變數,注意類物件與類的物件的區別,類物件指的是類本身因為類也是物件所以稱為類物件這是為了區別與普通物件而稱呼的,而類的物件是指由這個類所構造出來的物件。
ruby是由c語言實現的且ruby是純物件導向的語言,在ruby中一切都是物件。在內部實現中ruby任何物件都有以下三個變數:
2.iv_tbl,是乙個儲存該物件例項變數的雜湊資訊。
3.flags,顧名思義這是物件的標誌資訊變數,用以標誌物件是否被汙染是否被**是否被凍結等資訊。
如果物件是類(class)或者是模組(module)(ruby中一切都是物件),出了以上三個變數外,還有以下兩個量。
1.super指標,這個一看就知道是指向這個類的父類,有人可能會糊塗,類有父類這沒錯,模組不能繼承難道模組也有父類?的卻是有的。模組雖然不可以繼承,但乙個模組卻可以包含(include)另外乙個模組。當模組包含乙個模組時此模組的super指標就指向被包含模組所生成的虛擬類也或者是說**類(模組被包含都會生成**類以便模組插入繼承鏈中)
2.m_tbl,既然上面有個iv_tbl是例項變數表,那麼這個肯定是例項方法表。
有以上資訊可知,第一類跟模組也是物件包含普通物件所有的特徵。但類與模組也是特殊的物件除了普通物件的特徵外還有作為類與模組的特別的特徵。其次例項變數都是儲存在物件自己的資料結構中,而方法都是儲存在類中,並且類中儲存的方法只有例項方法。那麼類方法呢?其實類方法也是例項方法,是類的例項方法,儲存在類的單例類中。物件在呼叫方法時,首先沿著物件klass(klass所指的類不一定是直接生成這個物件的類也有可能個是這個物件的單例類)所指的類的方法表中(m_tbl)中尋找方法,若沒找到就通過super依次沿著繼承鏈尋找父類跟祖先類的方法表尋找此方法,知道找到所呼叫的方法或者沿著繼承鏈到object類。如果在object中也沒有此方法的定義則又從頭開始按照上述方法尋找method_missing這個方法。
繼續開頭講得那個有趣的事情。class是類也是物件class是本身的物件,class的klass指標指向自己。由上述我們可知方法都是儲存在類中的,當class作為乙個物件時他的方法儲存在**?自然是儲存class物件所屬的類中也就是class類本身當中。但如果class作為類通過class.new生存乙個普通物件時此時class類中儲存的也還是例項方法。但class類的類方法呢? 按道理class類方法也就class這個類物件的例項方法應該儲存在class這個類物件的單例類中。先看乙個例子:
我們重新開啟class類定義乙個方法
classclass
defshow
puts"hello"
endend
lass.new.show
輸出:hello
class.show輸出:hello
上述例子class類中定義的例項方法也成了類方法。為何?其實也不難理解,因為class做為類時儲存類的例項方法,由class類生成的普通物件即class.new這個物件的klass指標是指向class這個類的,根據方法尋找的規則所以class.new.show是呼叫class類的例項方法。而因為class類也是其本身的物件所以他的klass指標也是指向本身,所以通過class.show這中方式呼叫class類的類方法時還是呼叫的同乙個方法。這一切歸根結底是因為類也是物件在作為物件時是與普通物件並無差別,而所謂的類方法其實也是例項方法只不過是另外乙個類的例項方法而已。所以class類是物件還是先是類呢?...
但類物件與普通物件也不是完全是一樣的,請看下面例子:
irb(main):022:0>classclass
irb(main):023:1>@@a="a"
irb(main):024:1>@b="b"
irb(main):025:1>defshow
irb(main):026:2>puts@@a
irb(main):027:2>puts@b
irb(main):028:2>end
irb(main):029:1>end
=>nil
irb(main):030:0>class.showab
=>nil
irb(main):031:0>class.new.show
a>nil
還是重新開啟了class類,只不過在類中定義了兩個變數,乙個類變數@@a,乙個例項變數@b,為何同乙個方法卻輸出不同的結果呢?因為@b是在類域中定義的而不是方法域中定義的所以@b是class類物件的例項變數,所以class.show能夠列印出@b的值,而class.new.show方法是不能列印出@b的值,因為例項變數儲存在物件裡其他的任何物件都無法訪問到。類變數與類例項變數看起來很相似,但其實是有區別的,它們的區別就是類變數對這個類所生成的所有物件是也可見並且共享的,這也是它們唯一的區別。在類物件本身它們並無二致都可看作類的例項變數。
本文出自 「夢想成就未來」 部落格,請務必保留此出處
Ruby 類和物件
ruby是一種物件導向程式設計語言,具有物件導向的特性 封裝 抽象 繼承和多型性。在ruby中,類以關鍵字class開始,後面跟類名 應大寫 以end結束。例如 class customer end1.2 變數 ruby提供四種型別的變數 區域性變數 區域性變數是在方法中定義的變數。區域性變數在方法...
Ruby 中的類和物件
最近在ruby china中閒逛,無意中發現了一位提出的問題,這個問題相當有意思,並且促使我寫下了這篇部落格。原問題是這樣描述的 class object defdo it puts do it endend object do it 這個class method 怎麼來的?object new d...
Ruby 中的類和物件
近在ruby china中閒逛,無意中發現了一位提出的問題,這個問題相當有意思,並且促使我寫下了這篇部落格。原問題是這樣描述的 class object defdo it puts do it endend object do it 這個class method 怎麼來的?object new do...