Attributes:
反映的是object's state,我们可以认为 instance variables 就是用attributes来表示的,states是varibles的集合,包括instance variables和class variables(以后会提到)
Instance variables的访问:
Instance variables是不能通过ClassName.variable来访问,必须建立有关的method
class Song
def initialize(a,b,c)
@a=a
@b=b
@c=c
end
def to_s
"#@a,#@b,#@c"
end
end
class OtherSong < Song
def initialize(a,b,c,d)
super(a,b,c)
@d=d
end
def to_s
super + ",#@d"
end
end
song = OtherSong.new("a","b",123,"c")
puts song
puts song.a
结果:
a,b,123,c
a.rb:25: undefined method `a' for #<OtherSong:0x298e450 @a="a", @c=123, @b="b",
@d="c"> (NoMethodError)
产生NoMethodError
所以我们添加一个method---a
class OtherSong
def a
@a
end
end
结果:
a,b,123,c
a
这结果达到了我们的要求,但是,这也明显的打破了我们前面说过的一个约定:我们不应该轻易的使用variable,而应该使用method,以免捅破封装好的class,而额外增加了复杂度,但是这里我们不得不这么做,因为,我们是在重构一个类,而不是新生成或者是使用一个类,重构的前提是,了解内部构造。因此对上面的约定,加上一个限制:
在外部访问一个封装好的实现时,请使用methods(更加标准的说法是使用接口interfaces),即外部的访问一个class的instance variables,请通过methods来实现,即使你可以通过其他途径来实现,添加方法时,请先了解你的class
accessor methods
前面说的,对于instance variables访问的methods,我们称为accessor methods,一种习惯是:accessor method 和它对应的variable名字有一定的关系的,就像上面的@a,使用a来访问。如果写过java的朋友一定对getXXX和setXXX深有体会,我个人觉得实在是太麻烦了,假如一个类里面有10个可读写的方法,那么一定让你很不爽,不过这样的缺点可以通过IDE解决,不过ruby的做法是,通过语言层面来解决---我们可以这样添加3个方法:
class OtherSong
attr_reader :a, :b, :c #注意前面是没有def的
end
Symbol object
注意前面的 :a 这是一个表达式,它会返回一个对象 Symbol object,我们把形如:":a" 这样的表示叫做symbol literal ,比如说 :a 就返回一个和 a 有关的Symbol object。method a b c都是自动被建立的。Symbol是不这么简单,如果希望详细了解,请参考有关资料