Peanut's Book Shelf » 日志 » Why Ruby amazes me? PRuby Chap 3 类,对象和变量
Why Ruby amazes me? PRuby Chap 3 类,对象和变量
Gem Gatherer 发表于 2007-10-28 20:42:12
song = Song.new("Bicyclops", "Fleck", 260)
song.inspect -> # <Song:0x1c8ac8, @duration=260, @artist="Fleck",@name="Bicyclops">
inspect可以将ID和实例变量格式化。但它并不是一定合用。我们有一个可重载的消息to_s来发送给任何一个想要输出字符串表示的对象
class Song
def to_s
"Song: #@name--#@artist (#@duration)"
end
end
Inheritance and Messages
class KaraokeSong < Song # 派生自Song
def initialize(name, artist, duration, lyrics)
super(name, artist, duration)
@lyrics = lyrics
end
end
class KaraokeSong
# ...
def to_s
"KS: #@name -- #@artist (#@diration) [#@lyrics]"
end
end
这是糟糕的编程模式。当我们可以不直接显式调用父类的成员的时候,我们就不应该这么做。
def to_s
super + "[#@lyrics]" #很简洁:)
end
Ruby类的成员自动被设为私有。
Ruby的派生体系:
$$单派生的缺点:在现实世界中,对象通常都会从多个源继承属性
$$多派生的缺点:容易引起派生结构混乱
Ruby类只有一个父类。但是它可以从任意数量的mixin(类似于一种部分的类定义)中include功能。
class Song
def name
@name
end
end
这种情况下,我们用attr_reader快速创建这些方法
class Song
attr_reader :name, :artist, :duration #attr_reader实际上是一个方法,而:name等符号是其参数.它利用code evaluation动态
#的在Song中加入实例方法体(很好很强大:)
end
同样的还有可写属性设置attr_writer
可写的属性
在Ruby里,在外部要对一个属性赋值还有点难:
class Song
public @name=""
end
s = Song.new()
s.name = "..." ## 这个是不能通过编译的...-_-
要这样做,设置一个名字以等号结尾的方法:
class Song
def duration=(new duration)
@duration=new_duration
end
end
好了,万事俱备:)
Virtual Attributes
def duration_in_minites
@duration / 60.0 # force floating point. 这个duration_in_minutes就像一个属性一样。但内部实际没有和它对应的变量
end
# 设计程序时,哪些东西应该作为内部状态,哪些应该作为表现形式,是应该好好研究的。
class Example
def instance_method #instance method
end
def Example.class_method #class method
end
end
单件和其他构造函数
** Ruby里定义单件简单而又明确
class MyLogger
private_class_method :new # 注意: ":new"是一个整体
@@logger = nil
def MyLogger.create
@@logger = new unless @@logger # Coooooool!
@@logger
end
#可以用object.object_id来查看两个reference是否究竟真的指向同一个对象
访问控制
Public :可以被任何人调用。方法默认是public的(initialize除外。它是private的)
Protected:只能被定义了该方法的类或其子类的对象所调用
Private:不能被除self以外的接收者调用。
class MyClass
protected
def method1 #这里的protected是函数....
...
end
public :method1, :method4
protected :method2
end
Ruby变量的实质
Ruby变量并不是一个对象。而只是对对象的一个引用。
person1="Tim"
person2=person1
person1[0]='J'
person1 -> "Jim"
person2 -> "Jim"
person2 = person1.dup
person1 = "K"
person1 -> "Kim"
person2 -> "Jim"
person2 = person1
person1.freeze
person2[0] = "L"
将输出错误信息。
