跳至內容

方法與實例變數

我們可以透過使用更簡短的語法,將方法參數賦值給實例變數,來簡化我們的建構子。

class Person
  def initialize(@name : String)
    @age = 0
  end

  def age
    @age
  end
end

目前,除了使用名稱創建一個人之外,我們無法對該人做太多事情。他的年齡永遠會是零。所以讓我們添加一個方法,使人變老。

class Person
  def initialize(@name : String)
    @age = 0
  end

  def age
    @age
  end

  def become_older
    @age += 1
  end
end

john = Person.new "John"
peter = Person.new "Peter"

john.age # => 0

john.become_older
john.age # => 1

peter.age # => 0

方法名稱以小寫字母開頭,並且依照慣例,僅使用小寫字母、底線和數字。

Getter 和 Setter

Crystal 標準函式庫提供了巨集,可簡化 getter 和 setter 方法的定義。

class Person
  property age
  getter name : String

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

john = Person.new "John"
john.age = 32
john.age # => 32

有關 getter 和 setter 巨集的更多資訊,請參閱 Object#getterObject#setterObject#property 的標準函式庫文件。

附帶一提,我們可以在原始的 Person 定義內或在單獨的定義中定義 become_older:Crystal 會將所有定義組合到單一類別中。以下程式碼可正常運作。

class Person
  def initialize(@name : String)
    @age = 0
  end
end

class Person
  def become_older
    @age += 1
  end
end

重新定義方法與 previous_def

如果您重新定義一個方法,則最後的定義將優先。

class Person
  def become_older
    @age += 1
  end
end

class Person
  def become_older
    @age += 2
  end
end

person = Person.new "John"
person.become_older
person.age # => 2

您可以使用 previous_def 來調用先前重新定義的方法。

class Person
  def become_older
    @age += 1
  end
end

class Person
  def become_older
    previous_def
    @age += 2
  end
end

person = Person.new "John"
person.become_older
person.age # => 3

在沒有引數或括號的情況下,previous_def 會接收該方法的所有參數作為引數。否則,它會接收您傳遞給它的引數。

萬用初始化

實例變數也可以在 initialize 方法之外初始化。

class Person
  @age = 0

  def initialize(@name : String)
  end
end

這會將每個建構子中的 @age 初始化為零。這對於避免重複非常有用,而且可以在重新開啟類別並向其中新增實例變數時,避免 Nil 類型。