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