例項方法和類方法(三)

2021-08-29 09:07:49 字數 2704 閱讀 8087

這一次,讓我們搞一些破壞性實驗,來驗證上兩次的內容

第乙個破壞性實驗,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 我是靜態方法...