iT邦幫忙

DAY 20
0

Ruby女孩:10萬.times { puts "為什麼?" }系列 第 20

Ruby女孩(20):一次弄懂一件事,今天來分清楚實體方法跟類別方法的差異!

前兩天我們所示範的都是實體方法,你得真的.new出一個實體物件之後,才能使用的實體方法。今天我們來認識類別方法,類別方法顧名思義是給類別本身所使用的方法,它不需要製造出實體物件就可以使用,來看看以下例子:

class RubyGirl
  attr_accessor :age
  def initialize(ruby_skill=0)
    @ruby_skill = ruby_skill
  end

  def self.project(x=1)
    puts "每一個RubyGirl都有 #{x} 個project."
  end
end

比起昨天的程式碼,有沒有注意到多了一個名為self.project的方法,這個方法名稱很特別,前面加上了self(也可以把self改成RubyGirl,功能相同),像這樣在名稱前面上加上self或類別名稱的方法,都屬於類別方法,那類別方法怎麼調用呢?我們看看以下範例:

RubyGirl.age
NoMethodError: undefined method `age' for RubyGirl:Class

RubyGirl.project
=> "每一個RubyGirl都有 1 個project."

你可以注意到.age這個方法因為屬於實體方法,他必須要.new出一個實體物件後才能使用。但是.project是可以直接被類別名稱所使用(不需要製作出實體物件)!

annie = RubyGirl.new
=> #<RubyGirl:0x007fefc94a26d8 @ruby_skill=0>

annie.project
NoMethodError: undefined method `project' for #<RubyGirl:0x007fefc94a26d8 @ruby_skill=0>

但是當你實際.new出一個屬於RubyGirl的實體物件annie後,這個實體物件只能調用實體方法,他再調用.project方法就會噴錯,由此可知,實體物件是無法使用類別方法的!

由於上面的寫法每定義一個類別方法都需要在方法名稱前加上self,可能會讓程式碼不夠明確(書中所述),因此書中提到,有另一種寫法很符合D.R.Y(Don't Repeat Yourself)原則

class RubyGirl

  #實體方法放這裡

  class << self

    #類別方法放這裡

  end

end

所以我們可以把剛剛的程式碼改寫成:

class RubyGirl
  attr_accessor :age
  
  def initialize(ruby_skill=0)
    @ruby_skill = ruby_skill
  end

  class << self
    def project(x=1)
      puts "每一個RubyGirl都有 #{x} 個project."
    end
  end
end

有類別方法當然也會有類別變數,類別變數的寫法我們曾經在Ruby女孩(4)時有提過,另外也有"類別實體變數",明天再一次介紹吧。一次搞懂一件事,今天的重點就是要分清楚實體方法跟類別方法的差異,你也了解了嗎XD?

=================================================

20天!加油加油還有三分之一XD

Today I will do what others won't, so tomorrow I can do what others can't.


上一篇
Ruby女孩(19):類別中的getter與setter
下一篇
Ruby女孩(21):來聽聽類別變數與類別實體變數的自白(?)
系列文
Ruby女孩:10萬.times { puts "為什麼?" }30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言