Ruby class 基本的覆寫(override)及繼承(inheritance)
首先考考大家,以下寫法,如果呼叫Greeting.hello
出現的是哪一個結果呢?
class Greeting
def self.hello
"hello"
end
def self.hello
"say hi"
end
end
不知道各位猜對了嗎?比較晚出現的code,會將較早出現的code覆寫掉,所以答案是出現"say hi"
。
1. 覆寫
最近嘗試寫一些Ruby gem,才發現這些關於class很驚人的事情,從以上例子進行延伸,其實我們可以對Ruby當中既存的class和method進行任意的修改及延伸。這有什麼好處呢?主要是在設定不同class時,可以非常簡便的互相取用資源,也可以從既有的class取得內容、進行編修。
假設我們需要針對所有字串(String)增加一個method,可以直接呼叫String出來修改:
class String
def hello
"Hello #{self}"
end
end
"John".hello
# => "Hello John"
"Pan".hello
# => "Hello Pan"
這個觀念最厲害的地方在於不管我們使用什麼字串,由於都是屬於String這個class底下的物件,所以設定的method都可以套用上去。假如我們對既有的method不滿,也可以用這個方式來增補,例如我們希望將字串的downcase
和reverse
這兩個method合併為一個downswap
,那可以用以下寫法:
class String
def downswap
self.downcase.reverse
end
end
"APPLE".downswap
# => elppa
這樣設定好以後,就可以在字串上使用。
2. 繼承
另外,class也有繼承的概念,就像我們在Rails的controller當中,會看到ApplicationController < ActionController
的寫法,意思是所有在ActionController當中能夠使用的功能,都會繼承到ApplicationController裡面,也因此我們才有很方便的callbacks可以使用,例如before_filter
等等。
我們也可以在自訂的class當中使用繼承的觀念:
class Feature
attr_accessor :feature
def initialize(feature="safe")
@feature = feature
end
end
class Product < Feature
def price
"$ 500"
end
end
feature = Feature.new
feature.feature
# => "safe"
product = Product.new
product.feature
# => "safe"
從上面的例子可以看出,我們在Product
這個class中雖然什麼都沒有寫,但因為已經開宗明義寫出是從Feature
這個class繼承而來,所以所有變數、method都可以直接取用,算是非常方便的一個地方。另外還多了一個price
method可以取用,會顯示跟幫助國民黨一樣可以拿到的500元。
這兩個觀念對於class的編修非常基本,但對於了解整個Ruby和Rails的脈絡是非常有用,尤其是目標要自行撰寫gem或framework的朋友來說是非知道不可啊~