about 9 years ago

上一篇我們學到可以定義(Define)一個方法(Method)

本篇的重點

  1. 學習建立一個類別(Class)來集合許多的方法(Method)去運作這個程式
  2. 了解什麼是實例變數(Instance Variable, 又稱物件變數)
  3. 找出Class裡預設內建的Method
  4. 設定變數的存取權的方法

一樣請使用互動式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

延伸閱讀: 維基教科書(Ruby類別), Ruby使用手冊(Ruby類別), Ruby使用手冊(實例變數)

← [Learn Ruby] 1. 環境設定、變數與基本運用 [Learn Ruby] 3. 做個 MegaGreeter 程式 →
 
comments powered by Disqus