上一節中的水果 (Fruit) 類別具有兩個實例變數,一個用來描述水果的種類,一個用來描述水果的狀態。為該類別編寫了自訂的 inspect
方法後,我們才發現如果水果沒有這些特徵,就會顯得很不合理。幸好 Ruby 有方法能夠確保實例變數總是能夠初始化 (initialize)。
initialize
方法
每當 Ruby 建立一個新物件,就會尋找 initialize
方法,然後執行該方法。我們可以做一項很簡單的事,就是使用 initialize
方法將預設值加入所有實例變數,這樣 inspect
方法就有東西可以回報。
| def initialize
| @kind = "apple"
| @condition = "ripe"
| end
| end
nil
ruby> f4 = Fruit.new
"a ripe apple"
將假設 (assumption) 改為需求 (requirement)
有時候,預設值並不大合理, 例如有「水果預設種類」這種東西嗎?比較理想的是,要求創造水果時,即指定每件水果的種類。因此,我們要在 initialize
方法中加入一個形式引數 (formal argument), 供應至 new
的引數其實都傳遞至 initialize
。
| def initialize( k )
| @kind = k
| @condition = "ripe"
| end
| end
nil
ruby> f5 = Fruit.new "mango"
"a ripe mango"
ruby> f6 = Fruit.new
ERR: (eval):1:in `initialize': wrong # of arguments(0 for 1)
彈性初始化
從以上例子我們發現,引數與 initialize
方法關聯後,如果省略引述會產生錯誤。如果想要周到一點,我們可以設定一個預設值。
| def initialize( k="apple" )
| @kind = k
| @condition = "ripe"
| end
| end
nil
ruby> f5 = Fruit.new "mango"
"a ripe mango"
ruby> f6 = Fruit.new
"a ripe apple"
除了 initialize
以外,你也可於其他方法使用預設引數值。要注意的是,具有預設值的引數必須排在引數列的最後面。
為物件提供不同的初始化方式,有時候會頗有用處。本手冊並不包含物件反射 (object reflection) 及變數長度引數表 (variable-length argument list)的作法,但 Ruby 支援這些功能,能夠提供有效的方法重載 (method overloading)。