构造方法——new 与 initialize

现在,来看看另一个用户自定义类的例子。加载 7treasure.rb ,这是制作了一个冒险游戏。它包含两个类 Thing(东西) 和 Treasure(宝藏),Thing 类与 Cat 和 Dog 类特别的相似,除了它不包含 woof 或者 miaow。

Treasure 类没有 get_nameset_name 方法,相反地它包含一个名为 initialize 的方法,这个方法接受两个参数并将参数值分配给 @name@description 变量:

7treasure.rb
  1. def initialize( aName, aDescription )
  2. @name = aName
  3. @description = aDescription
  4. end

当一个类包含名为 initialize 的方法,它会在使用 new 方法创建对象时自动地被调用。使用 initialize 来设置一个对象的实例变量的值是不错的主意。

这相对于使用方法(例如 set_name)设置每个实例变量的值有两个明显的好处。首先,一个复杂的类可能包含许多实例变量,你可以通过一个 initialize 方法设置它们全部的值,而不是通过许多独立的“set”方法。其次,如果这些变量在对象创建时都被自动的初始化,你就不会以空的变量结束程序(例如在前面的程序中我们尝试显示 someotherdog 的名字时会返回 nil 值)。

最后,我创建了一个名为 to_s 的方法用来返回一个表示宝物对象的字符串。这个 to_s 方法名不是随意的,相同的方法名已被在 Ruby 标准对象库中使用。实际上,to_s 方法被定义在 Object 类中,该类是其它类的祖先。通过重新定义 to_s 方法,我添加了新的行为,这比默认的方法更适合于 Treasure 类。换句话说,我已经“覆盖”(overridden)了它的 to_s 方法。

new 方法可以创建一个对象,所以它可以被认为是对象的“构造方法”。然而,你通常不应该实现你自己的 new 方法(这是可能的,但它通常不可取)。相反,当你想要执行任何“设置”操作(例如为对象的内部变量赋值)时,应在 initialize 方法中完成,Ruby 会在一个新对象创建后立即执行 initialize 方法。

垃圾回收(Garbage Collection,GC)
在许多语言中(例如 C++ 和 Delphi for Win32),销毁任何已经创建并且不再需要的对象是程序员的职责。换句话说,对象被赋予析构函数以及构造函数。在 Ruby 中,你不必做这些了,因为 Ruby 有一个内置的“垃圾回收器”,它会在你的程序不再引用对象时销毁它并回收内存。