extend 和 extended
本章節我們將講解第二種混入方式:extend
。
1. extend
extend
可以擴展類或模塊里面的方法,與include
不同,extend
擴展的是類方法(Class Method)。
實例:
module Person
def name
"My name is Andrew"
end
end
class Member
extend Person
end
puts Member.name
# ---- 輸出結果 ----
My name is Andrew
解釋:如上面輸出結果展示的那樣,擴展后,模塊Person
為類Member
增加了一個名叫name
的類方法(類方法是以類名直接調用的方法)。
除此之外對象也可以對模塊進行extend
,模塊中的方法變成了實例方法(Instance Method),不過擴展的方法只針對一個對象有效。
實例:
module Person
def name
"My name is Andrew"
end
end
class Member
extend Person
end
member1 = Member.new
member2 = Member.new
member1.extend Person
puts member1.name
puts member2.name
# ---- 輸出結果 ----
My name is Andrew
ruby.rb:17:in `<main>': undefined method `name' for #<Member:0x00007ff5688f1c08> (NoMethodError)
解釋:member1
因為擴展了Person
模塊的方法,增加了實例方法name
,而member2
沒有進行擴展,因此拋出了沒有name
方法的異常。
2. extended
當我們extend
一個模塊的時候,就會觸發模塊的extended
回調函數。
讓我們修改一下上面的實例。
實例:
module Person
def self.extended(klass)
puts "#{klass} extended #{self}"
end
def name
"My name is Andrew"
end
end
class Member
extend Person
end
puts Member.name
# ---- 輸出結果 ----
Member extended Person
My name is Andrew
解釋:當模塊Person
被擴展后,會觸發extended
鉤子方法,率先打印了“Member extended Person”。
3. 小結
本章節我們學習了extend
,當類或模塊extend
一個模塊的時候,會將模塊中定義的方法填充進類或模塊的類方法中,另外,當一個模塊被extend
的時候,會觸發extended
回調,并返回操作的類名。