獨(dú)立站代運(yùn)營(yíng)公司站長(zhǎng)統(tǒng)計(jì)ios
Ruby和許多極為流行的編程語(yǔ)言都是面向?qū)ο蟮摹6鄶?shù)的面向?qū)ο缶幊陶Z(yǔ)言,每個(gè)對(duì)象都是一個(gè)樣例或者既定類的實(shí)例以及獨(dú)立對(duì)象的行為。
一、創(chuàng)建一個(gè)通用對(duì)象
創(chuàng)建一個(gè)通用對(duì)象
obj = Object.new
定義通用對(duì)象的行為
def obj.talk puts "I am an object"puts "(Do you object?)"
end
定義帶參數(shù)的方法
def obj.c2f(c)c * 9.0 / 5 + 32
end
任何方法的返回值與方法執(zhí)行中最后一個(gè)表達(dá)式的計(jì)算值相等
Ruby提供了一個(gè)關(guān)鍵字明確地定義了返回值:return,這個(gè)關(guān)鍵字地使用通常是可選的,但是多數(shù)程序員都喜歡用它,因?yàn)樗闺[式的返回值表達(dá)式變得顯而易見(jiàn)。
def obj.c2f(c)return c * 9.0 / 5 + 32
end
假如需要返回多個(gè)值則必須使用它,這些值會(huì)自動(dòng)被包裝為一個(gè)數(shù)組。
二、制作一個(gè)對(duì)象
一張入場(chǎng)券是一個(gè)常見(jiàn)的對(duì)象,且有一組眾人熟知的屬性和行為。這里將從一個(gè)較高的視角來(lái)看待一個(gè)如入場(chǎng)券般的Ruby對(duì)象能做什么以及該對(duì)象對(duì)自身的理解。
創(chuàng)建一個(gè)ticket.rb
ticket = Object.newdef ticket.date"01/02/03"
end
def ticket.venue"Town Hall"
end
def ticket.event"Author's reading"
end
def ticket.performer"Mark Twain"
enddef ticket.seat"Second Balcony, row J, seat 12"
enddef ticket.price5.50
end
這個(gè)馬克吐溫的入場(chǎng)券是一個(gè)簡(jiǎn)單的例子,但是它包含了一些Ruby編程的重要流程和原則。這個(gè)最重要的經(jīng)驗(yàn)就是:程序完成任何有用事情的信息都必須存儲(chǔ)于對(duì)象之中。ticket對(duì)象擁有這些信息,通過(guò)方法的調(diào)用可以請(qǐng)求ticket對(duì)象返回信息
查詢對(duì)象
print "This ticket is for: "
print ticket.event + ", at "
print ticket.venue + ", on "
puts ticket.date + "."
print "The performer is "
puts ticket.performer + "."
print "The seat is "
print ticket.seat + ", "
print "and it costs $"
puts "%.2f." % ticket.price
通過(guò)字符串插值縮短查詢代碼:
puts "This ticket is for: #{ticket.event}, at #{ticket.venue}" + "The performer is: #{ticket.performer}." + "The seat is: #{ticket.seat}, " + "The it costs #{"%.2f." % ticket.price}"
無(wú)論在插值運(yùn)算符中的內(nèi)容是什么,他都能被分步求值,求值的結(jié)果會(huì)被插入字符串中。
用方法表達(dá)布爾狀態(tài)
def ticket.avai_status"sold"
end
def ticket.avai?false
endif ticket.avai?puts "You are in luck!"
elseputs "Sorry--that seat has been sold."
end
注意方法avai?以問(wèn)號(hào)結(jié)尾
三、對(duì)象的原生行為
就算是新創(chuàng)建的對(duì)象也不會(huì)是一塊白板。只要對(duì)象創(chuàng)建并存在,它就能響應(yīng)一組消息。
輸入以下命令可以查看原生方法的列表:
Object.new.methods.sort
這些原生方法中的一小部分是非常普遍和非常有用的。
1、用object_id表示唯一標(biāo)識(shí)對(duì)象
在Ruby中,每個(gè)對(duì)象都有一個(gè)和它唯一關(guān)聯(lián)的ID編號(hào)??梢酝ㄟ^(guò)請(qǐng)求一個(gè)對(duì)象的object_id獲得一個(gè)對(duì)象的ID,使用如下類似的代碼。
obj = Object.new
puts "The id of obj is #{obj.object_id}."
str = "Strings are objects too, and this is a string!"
puts "The id of the string object str is #{str.object_id}."
puts "And the id of the integer 100 is #{100.object_id}"
運(yùn)行這段代碼可以看到
The id of obj is 60.
The id of the string object str is 80.
And the id of the integer 100 is 201
在嘗試確定兩個(gè)對(duì)象是否相等的時(shí)候,每個(gè)對(duì)象都擁有一個(gè)唯一的ID編號(hào)是很有用的,可以通過(guò)判斷object_id是否相等而判斷兩個(gè)對(duì)象是否相等。
a = Object.new
b = a
puts "a's id is #{a.object_id} and b's id is #{b.object_id}"
運(yùn)行之后可以看到a和b的對(duì)象id是相同的。
2、用respond_to?方法查詢對(duì)象的能力
Ruby對(duì)象響應(yīng)消息。在程序運(yùn)行期間的不同事件點(diǎn),依賴于對(duì)象和為對(duì)象定義的各種方法,一個(gè)對(duì)象可能會(huì)響應(yīng)指定的消息,也可能不會(huì)。所以可以使用respond_to?方法判斷一個(gè)對(duì)象是否有某種方法。
if obj.respond_to?("talk")obj.talk
else puts "Sorry, the object doesn't understand the 'talk' message"
end
該方法時(shí)自省或者反射的一個(gè)例子,這兩個(gè)詞指的是可以在程序運(yùn)行期間進(jìn)行狀態(tài)檢測(cè)。Ruby提供了許多用于自省機(jī)制的工具。使用methods方法測(cè)試對(duì)象,是另一種自省和反射的技術(shù)。
3、用send方法發(fā)送信息給對(duì)象
如果希望從鍵盤輸入合適的查詢?cè)~組(venue、performer等),就能從ticket對(duì)象中得到信息,則需要把如下代碼添加到已有的程序中:
print "Information desired: "
request = gets.chomp
該行代碼可以從鍵盤中獲取一行輸入。這樣可以使用雙等號(hào)比較符測(cè)試兩個(gè)不同的輸入值,它會(huì)基于對(duì)象自身的內(nèi)容對(duì)字符串進(jìn)行比較,然后調(diào)用與值匹配的方法。
if request == "venue"puts ticket.venue
elsif request == "performer"puts ticket.performer
......
盡管如此,還是不得不繼續(xù)編寫整個(gè)入場(chǎng)券的屬性列表,但那變得有些冗余了。
這里還有一個(gè)可選的方案:給ticket對(duì)象直接發(fā)送對(duì)應(yīng)的詞語(yǔ)。按如下方式替換前面例子里的代碼:
if ticket.respond_to?(request)puts ticket.send(request)
else puts "No such information available"
end
這個(gè)版本中使用了send方法作為ticket對(duì)象獲得消息的通用入口。這樣可以避免整個(gè)可能的請(qǐng)求清單,并由處理ticket對(duì)象的消息執(zhí)行該消息,以取代檢查ticket對(duì)象所具有的能力。
還可以使用__send__或者public_send代替send,__send__方法比普通send更安全,而public_send不能訪問(wèn)私有方法。
四、方法參數(shù)
在編寫方法的時(shí)候允許傳遞任意數(shù)量的參數(shù),在單獨(dú)的方法參數(shù)名稱前使用一個(gè)*即可:
def obj.multi_args(*x)puts "I can take zero or more arguments!"
end
符號(hào)*x表示在調(diào)用方法的時(shí)候,可以提供任意數(shù)量的參數(shù)。變量x被分配一個(gè)對(duì)應(yīng)任意參數(shù)的數(shù)組??梢栽谏院笫褂脭?shù)組每次測(cè)試其中的一個(gè)。
一般情況下,參數(shù)都是變量的引用,如果不想變量發(fā)生變化,可以傳入s.dup復(fù)制了一個(gè)對(duì)象。
def change_string(s)s.replace("New String!")
end
s = "Original String"
change_string(s)
change_string(s.dup)
還可以凍結(jié)一個(gè)變量,凍結(jié)后不能再對(duì)這個(gè)變量發(fā)生改變
s.freeze