跳至内容

方法和实例变量

我们可以使用更简洁的语法将方法参数赋值给实例变量,从而简化构造函数。

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 的文档。

顺便说一下,我们可以将 become_older 定义在原始的 Person 定义中,或者在单独的定义中: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 类型。