上一篇我們學到可以定義(Define)一個方法(Method)
本篇的重點
- 學習建立一個類別(Class)來集合許多的方法(Method)去運作這個程式
- 了解什麼是實例變數(Instance Variable, 又稱物件變數)
- 找出Class裡預設內建的Method
- 設定變數的存取權的方法
一樣請使用互動式Ruby環境(IRB, Interactive Ruby)來操作
如果使用 Mac OS X, 請打開 Terminal, 然後輸入
$ irb
按 Enter
如果使用 Linux, 請打開 Shell, 然後輸入$ irb
按 Enter
如果使用 Windows, 請從選單中打開Ruby的『fxri』
建立一個叫做Greeter的類別(Class)
輸入以下內容
> class Greeter # 宣告設定一個類別(class)叫做Greeter(一定要大寫)
> def initialize(name = "World")
> @name = name
> end
> def say_hi
> puts "Hi #{@name}!"
> end
> def say_bye
> puts "Bye #{@name}, come back soon."
> end
> end
=> nil
在程式碼前面加上 # 符號,就會變成單行註解,Ruby運作時會自動忽略註解的內容
多行註解的寫法:
=begin
...
...
=end在Ruby裡類別的命名慣例是第一個字大寫,不填空格以及"-" or "_"來設定類別名稱,
EX: MyClass, BasicActive, ShowTtime@name 的意思是設定一個實例變數(Instance Variable,或是稱為物件變數),名字是name,要設定實例變數才能給後面的方法(也就是say_hi, say_bye)來當作一個物件來使用
接下來試試看這個Class怎麼運作
> c = Greeter.new("Jack") #設定一個物件c,依照Greeter這個類別來運作,並設定參數"Jack"到Greeter裡面
=> #<Greeter:0x007fc66315b630 @name="Jack">
> c.say_hi #執行物件c的方法(Method):say_hi
Hi Jack!
=> nil
> c.say_bye #執行物件c的方法(Method):say_bye
Bye Jack, come back soon.
=> nil
一旦建立了 c 這個物件,它會記住他的名字是 Jack,可是卻無法直接取出 @name 也就是他的名字的內容出來
> c.@name
SyntaxError: (irb):24: syntax error, unexpected tIVAR, expecting '('
from /Users/sdlong/.rvm/rubies/ruby-2.0.0-p353/bin/irb:12:in `<main>'
解析物件
因為Ruby使用物件導向的思維,內部屬性資料是隱藏起來的,所以連同實例變數(Instance Variable)也被隱藏。
可以輸入以下指令來找出 Greeter 裡含有哪些方法(method)
> Greeter.instance_methods
=> [:say_hi, :say_bye, :nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, :dup, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :extend, :display, :method, :public_method, :define_singleton_method, :object_id, :to_enum, :enum_for, :==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__]
我們在Class Greeter裡面只有設定二個方法: say_hi跟say_bye, 會跑出那麼多,是因為其他都是Ruby裡預設內建的
新建出來的類別(Class),會自動繼承父類別的方法,可以加入flase這個參數指令過濾掉父類別的方法
> Greeter.instance_methods(false)
=> [:say_hi, :say_bye]
可以用內建的method: .respond_to?() 來測試這個 class Greeter 對哪些method有反應
> c.respond_to?("say_hi")
=> true
> c.respond_to?("to_s") #將此物件轉換成字串的method, 所有的物件都有內建)
=> true
> c.respond_to?("name")
=> false # 代表無反應
建立變數的修改、讀取權限
修改Class Greeter,增加一段程式碼來存取 name這個變數
> class Greeter
> attr_accessor :name
> end
=> nil
接下可以測試看看了
> c.respond_to?("name")
=> true # 對name這個Method有反應了
> c.respond_to?("name=")
=> true # 對name= 這個Method有反應了
> c.say_hi
Hi Jack! # 還是原本的Jack
=> nil
> c.name="Mary"
=> "Mary" # 改成 Mary了
> c.say_hi
Hi Mary!
=> nil
> c.name
=> "Mary" # 可以叫出 name 這個變數出來了
attr_accessor 會設定二個新的method, 以本例來說 name 用來取(read)值, name=用來給(write)值
也可以設定:
attr_writer 只能寫入
attr_reader 只能讀取
結尾
不過癮!只能一次處理一個人?
下一章來做個 MegaGreeter,可以歡迎不同人,甚至一群人
附註
實例變數(Instance Variable, 又稱物件變數)
簡單來說,是個把變數化作物件,來讓方法(Method)使用
除非設定attr_accessor屬性,不然把變數給定義(Define)完後就不能再修改,也不能直接叫出,只能在Method內使用
例如:
class MyClass
@one = 1 # 沒在Method內
def do_something
@one = 2 @ # 放在Method內
end
def output
puts @one
end
end
測試1
> d = MyClass.new # 設定d 物件,使用 MyClass這個類別(Class)
=> #<MyClass:0x007f8a52066678>
> d.output # c物件使用output
# 無任何內容
=> nil # 程式結束
測試2
> e = MyClass.new
=> #<MyClass:0x007f8a52047a98>
> e.do_something # e物件使用do_something
=> 2 # 裡面的值
> e.output
2 # 輸出2 這個數據
=> nil