Answers:
@age
直接写访问实例变量@age
。编写过程self.age
告诉对象向自身发送消息age
,该消息通常将返回实例变量@age
-但可以执行任何其他操作,具体取决于在age
给定子类中方法的实现方式。例如,您可能有一个MiddleAgedSocialite类,该类总是报告其年龄比实际年龄小10岁。或更实际地说,PersistentPerson类可能会从持久性存储中延迟读取该数据,并将其所有持久性数据缓存在哈希中。
不同之处在于,它将方法的使用与方法的实现隔离开来。如果要更改属性的实现(例如保留出生日期,然后根据现在和出生日期之间的时间差来计算年龄),则无需更改取决于方法的代码。如果它直接使用该属性,则更改将需要传播到代码的其他区域。从这个意义上讲,直接使用属性比使用类提供的接口更脆弱。
当您继承一个类时会被警告,该类Struct.new
是一种生成初始化器的好方法(如何在Ruby中生成初始化器?)
class Node < Struct.new(:value)
def initialize(value)
@value = value
end
def show()
p @value
p self.value # or `p value`
end
end
n = Node.new(30)
n.show()
将返回
30
nil
但是,当您删除初始化程序时,它将返回
nil
30
用类定义
class Node2
attr_accessor :value
def initialize(value)
@value = value
end
def show()
p @value
p self.value
end
end
您应该提供构造函数。
n2 = Node2.new(30)
n2.show()
将返回
30
30
第一个答案是完全正确的,但是作为一个相对新手,我并没有立即明白它所暗示的含义(向自己发送消息吗?呃……)。我认为一个简短的例子会有所帮助:
class CrazyAccessors
def bar=(val)
@bar = val - 20 # sets @bar to (input - 20)
end
def bar
@bar
end
def baz=(value)
self.bar = value # goes through `bar=` method, so @bar = (50 - 20)
end
def quux=(value)
@bar = value # sets @bar directly to 50
end
end
obj = CrazyAccessors.new
obj.baz = 50
obj.bar # => 30
obj.quux = 50
obj.bar # => 50