iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
自我挑戰組

入坑 RoR 必讀 - Ruby 物件導向設計實踐系列 第 24

Day24 Ruby物件導向實踐-initialize 和attribute accessors

  • 分享至 

  • xImage
  •  

大家對於方法的定義和使用大致理解後,今天想跟大家聊聊ruby內特別的方法,大家有印象我在前兩天的舉例都會在類別內定義一個initialize方法以及attribute accessor嗎?

initialize

定義

initialize顧名思義就是初始化,他是一個特殊的構造方法(constructor method),是Ruby在建立物件(object)過程中的一個環節。Ruby允許我們在建立物件時執行一些初始化的操作,也就是說當你new出一個物件時,initialize方法會自動被調用,藉由initialize賦予物件初始的值、行為或狀態。

class Person
  def initialize(name, age)
    @name = name
    @age = age
  end

  def introduce
    puts "Hi, I'm #{@name}, and I'm #{@age} years old."
  end
end

# 建立 Person 實體時,自動調用 initialize 方法
amanda = Person.new("Amanda", 28) #<Person:0x0000555e7b1ba0b0 @name=Amanda, @age=28>

# 調用對象的方法
puts amanda.introduce # "Hi, I'm Amanda, and I'm 28 years old."

更進一步,我們希望person物件在建立時都帶有初始值,那我們可以使用運算符or(’||’)來提供默認值,如果傳遞給建構方法的參數agenil(即沒有傳遞參數),統一都會是18

class Person
  def initialize(name, age)
    @name = name
    @age = age ||= 18
  end
end

# 建立 Person 實體時,自動調用 initialize 方法
amanda = Person.new("Amanda", 28) #<Person:0x0000555e7b1ba0b0 @name="Amanda", @age=28>
lilith = Person.new("Lilith") #<Person:0x0000534i7e2ca1a0 @name=Amanda, @age=18>

attribute accessors

屬性?

Ruby 並沒有定義「屬性」,因此,當我們直接取用實體變數時,會出現錯誤:

class Person
  def initialize(name, age)
    @name = name
    @age = age
  end
end

# 建立 Person 實體時,自動調用 initialize 方法
amanda = Person.new("Amanda", 28)
amanda.name # NoMethodError: undefined method 'name'

需要另外定義方法,因為只有方法可以取用實體變數。

class Person
  def initialize(name, age)
    @name = name
    @age = age
  end

  def introduce
    puts "Hi, I'm #{@name}, and I'm #{@age} years old."
  end

  def name
    @name
  end

  def name=(value)
    @name = value
  end
end

# 建立 Person 實體時,自動調用 initialize 方法
amanda = Person.new("Amanda", 28)
amanda.name = "New Amanda"
puts amanda.name # "New Amanda"

定義

為了解決這個問題,Ruby 有幫我們定義了1個方法:attr_accessor,讓我們可以更輕鬆的來取用實體變數

class Person

  attr_accessor :name
  # 替我們建立 name, name=

  def initialize(name, age)
    @name = name
    @age = age
  end

  def introduce
    puts "Hi, I'm #{@name}, and I'm #{@age} years old."
  end

  #def name
    #@name
  #end

  #def name=(value)
    #@name = value
  #end
end

# 建立 Person 實體時,自動調用 initialize 方法
amanda = Person.new("Amanda", 28)
puts amanda.name # "Amanda"

除了attr_accessor 還有 attr_readerattr_writer ,相較於attr_accessor可以一次創建getter和setter,attr_reader 只有讀取實體變數的功能,不能改變資料,需要搭配attr_writer 才能改變資料。

結論

我的理解是把initializeattribute accessors作為建立一個新類別時的起手式,可以在定義類別時先建立好需要的資料,某種程度上也是類別藍圖的一部分,明確的知道他帶有哪些行為或狀態,並且能彈性的取用和修改行為或狀態。

參考資料:


上一篇
Day23 Ruby物件導向實踐-方法
下一篇
Day25 Ruby物件導向實踐-block, proc, lambda
系列文
入坑 RoR 必讀 - Ruby 物件導向設計實踐30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言