Programming Ruby学习笔记二
第三章 类、对象和变量
Ruby中initialize相当于Java里面的构造函数。当调用new创建一个新的对象时,Ruby首先分配一些内存来保存未初始化的对象,然后调用对象的initialize方法,并把调用new时所使用的参数传入该方法。
Inspect方法(可以发送给任何对象)默认将对象的ID和实例变量格式化。
Ruby有一个标准消息to_s,可以发送给任何一个想要输出字符串表示的对象。
要注意的一点是,Ruby中的类永远都不不是封闭的,可以向一个已有的类中添加方法。这适用于自己编写的类,也使用于标准的内建(bulit-in)类。只要打开某个已有类的类定义,就可以将指定的新内容添加进去。
3.1 继承和消息
类定义中使用”<”可以指定父类,如”KaraokeSong < Song”中,KaraokeSong是Song的子类(subclass)。
当调用super而不使用参数时,Ruby想当前对象的父类发送一个消息,要求它调用子类中的同名方法。Ruby将我们原先调用方法时的参数传递给父类的方法。
如果在定义一个类时没有指定父类,将默认以Object类作为其父类。这意味着所有类的始祖都是Object,并且Object的实例方法对Ruby所有对象都可用。
3.2 对象和属性
通常会定义一些方法来访问及操作对象的状态,让外部世界得以与之交互。一个对象的外部可见部分被称为属性(attribute)。
Ruby提供了attr_reader创建相关实例变量的访问方法。如 “attr_reader :name,:artist,:duration”,将创建name,artist,duration的访问方法。
可以通过创建一个名字以等号结尾的方法来达成对实例变量赋值。这些方法可以作为赋值操作的目标。实际上,定义一个以等号结尾的方法名,便使其能够出现在赋值操作的左侧。
Ruby提供了attr_writer创建相关实例变量的设置方法。
根据统一访问原则(Uniform Access Principle),可以设置虚拟属性来隐藏实例变量与计算的值的差异,以此来实现对外部世界屏蔽类。
3.3 类变量和类方法
对一个给定的类来说,类变量只存在一份拷贝。类变量有两个@@开头。类变量在使用之前必须被初始化。通常,初始化就是在类定义中的简单赋值。
类方法和实例方法是通过它们的定义区别的:通过在方法名之前放置类名以及一个句点,来定义类方法。
可以使用类方法作为伪构造函数(pseudo-constructors)。
3.4 访问控制
一个经验法则:永远不要暴露会导致对象处于无效状态的方法。
Public(公有)方法可以被任何人调用,没有限制访问控制,方法默认就是public的(initialize除外,它是private的)。
Protected(保护)方法只能被定义了该方法的类或其子类的对象所调用。整个家族均可访问。
Private(私有)方法不能被明确的接收者调用,其接收者只能是self。这意味着私有方法只能在当前对象的上下文中被调用,不能调用另一个对象的私有方法。
有两种方式使用public、protected、private这3个函数来指定访问级别。如果使用时没有参数,这3个函数设置后续定义方法的默认访问控制。另外可以通过将方法名作为参数列表传入访问控制函数来设置访问级别。注意:设置方法的访问级别时,需确认已定义了该方法。
3.5 变量
变量只是对象的引用。对象漂浮在某处一个很大的池中(大多数是堆),并由变量指向它们。可以理解为变量存放的是对象的指针。
赋值别名(alias)对象,潜在地给了引用同一对象的多个变量。
可以通过冻结一个对象来阻止其他人对其进行改动。