這一次,讓我們搞一些破壞性實驗,來驗證上兩次的內容
第乙個破壞性實驗,module裡定義self.***方法
ruby **
irb(main):001:0> module m
irb(main):002:1> def
self.method_with_self
irb(main):003:2> end
irb(main):004:1> end
=> nil
irb(main):005:0> class a
irb(main):006:1> include m
irb(main):007:1> end
=> a
irb(main):008:0> a.methods - class.methods
=> #空的,你能想到為什麼麼?
讓我仔細看看,我們定義的方法呢?
ruby **
irb(main):009:0> m.singleton_methods
=> ["method_with_self"] #原來跑到m的單例類裡面去了,別忘了,module也是class
好了,上面是include,那麼,extend會發生什麼情況呢?
ruby **
irb(main):010:0> class b
irb(main):011:1> end
=> nil
irb(main):012:0> b.extend m
=> b
irb(main):013:0> b.ancestors
=> [b, object, kernel]
ok,再來讓我們看看b的單例類此時發生了什麼變化
ruby **
irb(main):014:0> singleton_class_of_b = class
=> #
irb(main):015:0> singleton_class_of_b.ancestors
=> [m, class, module, object, kernel] #正如我們預料的,m變成了b單例類的直接父類
正如預料的,m變成了b單例類的直接父類,m中定義的例項方法,變成了b的類方法(因為m中的例項方法被b的單件類繼承,變成了單件類的例項方法,也就是b的類方法),m中定義的以self開頭的類方法呢?當然仍然在m的單件類裡面啦,它是不會隨著m插入點的變化而變化的。
第二個破壞性實驗,單件類中的self.***方法?
ruby **
irb(main):001:0> class a
irb(main):002:1> end
=> nil
irb(main):003:0> class
def
self.method_defined_in_singleton_class_of_a
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> a.singleton_methods
=> #看來定義的singleton方法並不屬於a
irb(main):008:0> singleton_class_of_a = class
=> ##a的單件類
irb(main):009:0> singleton_class_of_a.singleton_methods
=> ["method_defined_in_singleton_class_of_a", "new", "nesting"]
#原來變成了a的單件類的singleton方法
看了上面**後想想其實很自然,我們之前說過「所有的類方法都是放在這個類物件的單例類中」,所以,我們新建的這個方法method_defined_in_singleton_class_of_a實際上是放到了a的singleton class 的singleton class>中的。
第三個破壞性實驗,找不到直接父類m?
ruby **
irb(main):001:0> module m
irb(main):002:1> def
self.class_method_defined_in_m
irb(main):003:2> puts "singleton method in m"
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> class a
irb(main):007:1> include m
irb(main):008:1> end
=> a
irb(main):009:0> a.ancestors
=> [a, m, object, kernel]
irb(main):010:0> a.superclass
=> object
上面irb結果可以看到,從繼承樹上來看a的直接父類是m,但是當我們呼叫a.superclass的時候卻跳過了這個m,為什麼呢?正如之前所說,我們在繼承樹上看到的m,其實只是m的乙個**,他的作用僅僅是用來做方法查詢,讓a變成乙個**類的子類,是沒有意義的,所以,雖然實際上a確實稱為了**類的子類,但是從邏輯上講,它的繼承關係並沒有被改變,它從邏輯上仍然是object的直接子類
類方法和例項方法?
筆試中遇到都最最基礎的問題,我竟然有點懵了。首先沒弄清楚什麼是類方法,什麼是例項方法,現在就做乙個總結。類中的方法分為類方法和例項方法。類方法 類中用 static 修飾的方法。例項方法 也稱為物件方法,除了類方法都是例項方法。類方法在類被 jvm 虛擬機器載入進記憶體的時候就會為其分配入口位址,例...
例項變數和類變數 類方法和例項方法
類體中包括成員變數和區域性變數,而成員變數又可以細分為例項變數和類變數,在宣告成員變數的時候,用static給予修飾的稱作類變數,否則稱作例項變數。類變數也稱為static變數,靜態變數 那麼,類變數和例項變數有什麼區別呢?我們知道,乙個類通過使用new運算子可以建立多個不同的物件,這些物件將被分配...
例項方法,類方法和物件方法
class a num 10 def hehe self print 我是例項方法 也叫物件方法 classmethod def haha cls print 我是類方法,我的第乙個引數代表的是類,例如本例是a cls.num staticmethod def heihei print 我是靜態方法...