變量與賦值
至此,你是否注意到前面所有的示例代碼中都缺少某種東西?難道你必須輸入常數(shù),實(shí)例變量或類變量?絕對(duì)不是!這正是Ruby的真正面向?qū)ο蟮奶煨缘囊徊糠帧榇耍紫茸屛覀兛匆幌翿uby中以前的普通變量。至此,你已經(jīng)創(chuàng)建了很多Rectangle實(shí)例,但是你并沒(méi)有把它們保留多長(zhǎng)時(shí)間。比方說(shuō),你想要把一個(gè)變量賦值給你創(chuàng)建的一個(gè)Rectangle實(shí)例:
myRectangle?=?Rectangle.new(4,5) |
在Ruby中這是完全有效的代碼,而且根本不需要另一行代碼來(lái)把myRectangle類型化或聲明為引用Rectangle的某種東西。在執(zhí)行這一行代碼以后,變量myRectangle就引用一個(gè)Rectangle的實(shí)例(高度和寬度值分別為4,5)。但是,這僅是一種在任何時(shí)刻都可以更改的對(duì)象引用,而與對(duì)象的類型無(wú)關(guān)(在Ruby中一切都是對(duì)象)。因此,下面的命令提示符行中,你可以容易地把myRectangle賦值給一個(gè)字符串:
irb(main):049:0< myRectangle=Rectangle.new(4,5) => #<Rectangle:0x587c758 @width=5, @height=4> irb(main):050:0< myRectangle="Jim's Rectangle" => "Jim's Rectangle"
|
你可以在許多其它程序語(yǔ)言(甚至包括象Java這樣的面向?qū)ο蟮恼Z(yǔ)言)中試驗(yàn)一下,并觀察從你的IDE所產(chǎn)生的編譯錯(cuò)誤。
變量,實(shí)例變量,類變量,甚至還有"常量"其實(shí)都只是對(duì)象引用。它們引用對(duì)象,但是它們并不是對(duì)象本身。因此,它們可以被動(dòng)態(tài)地改變,甚至引用另一種不同類型的對(duì)象。
因?yàn)檫@一靈活性,所以必須在Ruby中進(jìn)行一些約定以幫助每個(gè)人都知道某個(gè)變量正為代碼所使用。其實(shí),你已經(jīng)看到了其中之一(@符號(hào),它意味著這是一個(gè)實(shí)例變量)。其它的變量,方法和類命名約定列于下表1中。
- · 局部變量和方法參數(shù)以一個(gè)小寫(xiě)字母開(kāi)頭。
- · 方法名字以一個(gè)小寫(xiě)字母開(kāi)頭。
- · 全局變量以一個(gè)$開(kāi)頭。
- · 實(shí)例變量以一個(gè)@開(kāi)頭。
- · 類變量以兩個(gè)@開(kāi)頭。
- · 常數(shù)以一個(gè)大寫(xiě)字母開(kāi)頭(它們經(jīng)常被指定全部大寫(xiě))。
- · 類和模塊名以一個(gè)大寫(xiě)字母開(kāi)頭。
?局部變量 |
?全局變量 |
?實(shí)例變量 |
?類變量 |
?常數(shù) |
?類名 |
?方法名 |
?aVar |
?$Var |
?@var |
?@@var |
?VAR |
?MyClassmy |
?Method |
?name |
?$debug |
?@lastName |
?@@interest |
?PI |
?Rectangle |
?area |
表1.這個(gè)表包含了在Ruby編碼約定下的相關(guān)示例。
操作符方法
現(xiàn)在,假定你想實(shí)現(xiàn)合并Rectangle類的實(shí)例或把它們添加到另一個(gè)Rectangle實(shí)例。你當(dāng)然可以定義另外一個(gè)稱為"add"的方法,這種選擇利用了Ruby真正的面向?qū)ο蟮奶卣髦弧H欢氵€可以重載"+"運(yùn)算符來(lái)適當(dāng)?shù)匕褍蓚€(gè)Rectangle實(shí)例加起來(lái)。這個(gè)"+"方法(如4+5),對(duì)Ruby來(lái)說(shuō),只是另外一個(gè)方法而已。由于只是"另外一個(gè)方法",所以你可以給它增加一些功能來(lái)滿足Rectangle類的需要。例如,你還可以定義"+"運(yùn)算符來(lái)實(shí)現(xiàn)一個(gè)矩形面積加上另一個(gè)矩形面積。
def + (anotherRectangle) totalArea = area() + anotherRectangle.area() Rectangle.new(@height,totalArea/@height) end
|
在把這個(gè)方法添加到Rectangle類以后,你可以使用+方法調(diào)用來(lái)把兩個(gè)Rectangle的實(shí)例相加:
irb(main):001:0> rect1=Rectangle.new(2,3) => #<Rectangle:0x58aa688 @width=3, @height=2> irb(main):002:0> rect2=Rectangle.new(3,4) => #<Rectangle:0x58a6ef0 @width=4, @height=3> irb(main):003:0> rect1+rect2 => #<Rectangle:0x58a4a60 @width=9, @height=2>
|
這正是操作符重載,對(duì)于那些使用過(guò)Agol,C++,Python和其它語(yǔ)言的用戶來(lái)說(shuō),可能已經(jīng)非常熟悉這個(gè)特征。
方法參數(shù)
至此,我們一直假定,傳遞給一個(gè)方法的參數(shù)個(gè)數(shù)是已知的。也許在其它語(yǔ)言中不可思議,但是Ruby的確允許你傳遞可變個(gè)數(shù)的參數(shù)并且以單個(gè)參數(shù)來(lái)捕獲它們。為了創(chuàng)建一個(gè)可變長(zhǎng)度的參數(shù),只需要把一個(gè)星號(hào)(*)放在最后一個(gè)參數(shù)前面即可。這樣,你就可以在Ruby中編寫(xiě)一個(gè)如下的多邊形定義。
class Polygon def initialize (s1,s2,s3,*others) @sideOne = s1 @sideTwo = s2 @sideThree = s3 @otherSides = others end end |
如下所示,你可以使用這個(gè)定義來(lái)創(chuàng)建一個(gè)三角形或一個(gè)六邊形。
irb(main):009:0> poly1=Polygon.new(2,4,5) => #<Polygon:0x594db10 @otherSides=[], @sideThree=5, @sideTwo=4, @sideOne=2> irb(main):010:0> poly2=Polygon.new(2,18,4,5,7,9) => #<Polygon:0x5948d58 @otherSides=[5, 7, 9], @sideThree=4, @sideTwo=18, @sideOne=2>
|
在支持可變長(zhǎng)度參數(shù)的同時(shí),Ruby還允許定義一個(gè)方法參數(shù)的默認(rèn)值(在調(diào)用者沒(méi)有提供的情況下使用)。例如,下面是Rectangle類的一個(gè)更好的初始化表達(dá)。
def initialize (hgt = 1, wdth = 1) @height = hgt @width = wdth end
|
現(xiàn)在,在調(diào)用時(shí)如果省略了某參數(shù),那么在定義中參數(shù)緊鄰的賦值運(yùn)算符擔(dān)當(dāng)一個(gè)缺省的賦值器。現(xiàn)在,當(dāng)創(chuàng)建一新的矩形時(shí),如果在調(diào)用時(shí)省略了寬度,那么一個(gè)適當(dāng)?shù)膶挾纫矔?huì)被默認(rèn)地提供:
irb(main):090:0> rect=Rectangle.new(2) => #<Rectangle:0x5873f68 @width=1, @height=2>
|