- 论坛徽章:
- 0
|
A.10 面向对象
“Ruby中几乎一切都是对象”——请记住这句话
2.times #这是发送一个times消息给2这个对象,即意味着2是一个对象,是Fixnum类的一个对象,puts 2.class 可以查看出
OK,看看ruby类和常对象的常规应用
1、ruby类也是由方法和属性构成,与语言一样
2、ruby也有静态方法(类方法)、实例方法之分,也有静态属性(类属性)与实例属性之分(当然,也有常量)
类属性用@@作为前缀,实例属性用@作为前缀
下面来定义一个类- class A
- @@class_var=3 #类属性
- def self.set_class_var(x) #类方法
- @@class_var=x
- end
- def A.get_class_var #类方法
- @@class_var
- end
- def hello #实例方法
- @a=\"in hello\" #实例属生
- puts @a
- end
- end
复制代码 就这么简单- t1=A.new #得到一个A的实例对象
- t1.hello
- A.set_class_var(5)
- A.get_class_var
复制代码 ruby的类有构造函数,名称固定:initialize
简单的基础部分就说这么多,看些高级点的应用
3、ruby的任何一个类都是Object的子类,因此,Object中定义的实例方法和实例属性,会被所有类继承
4、回顾第一句话“几乎任何东西都是对象”,连类的定义体本身也是一个对象,是谁的对象了?Class类的。
看看ruby类的源码中的C结构体- typedef unsigned long VALUE;
- struct RBasic {
- unsigned long flags;
- VALUE klass;
- };
- struct RClass {
- struct RBasic basic;
- struct st_table *iv_tbl;
- struct st_table *m_tbl;
- VALUE super;};
复制代码 *iv_tbl指针指向的是存类的实例变量(注意,是类定义体本身对象的,对于类来说)
*m_tbl指针指向的是存类的实例方法(对于类本身对象来说)
那么类的类方法(静态方法)存在哪了?
ruby很狡猾的创建了一个“虚拟类”,然后让类本身的kclass指针指向虚拟类,类的静态方法是存在这个类中。虚拟类是隐藏的,用户并不知的。
以上有点难理解,请认真分析一句话“类定义体本身也是一个对象是Class的一个对象”,这个对象是用一个常量——类名来引用的。
因此我们可以:
C=Class.new
就创建了一个C类
5、再回顾第一句话“几乎任何东西都是对象”
block可以转化为Proc对象
类中的方法也可以转为对象——Method(UnBoundMethod)
不过,这个地方要注意一点,再请记住一句话:任何方法的调用(或叫消息发的送)必须有一个消息的接受者,如果没指定,隐含使用self
那么,当你创建了一个Method对象后,需要将这个Method对象绑定到某个Object上后,才可调用此method,例:- class A
- def x
- puts \"in x\"
- end
- end
- mo=A.instance_method(:x) #创建A类中的x方法的对象用mo指向
- puts mo.class #返回为NoBoundMethod,还没有绑定这个实例方法到某个对象身上,因此无法调用
- object=A.new
- xx=mo.bind(object) #绑定mo方法对象到object对象身上
- puts xx #返回Mehtod,说明绑定了
- xx.call #可执行了。
复制代码 这个有点难理解,不过把握住关键的几句话也是好理解的。
上面是方法的另一种调用方式,再看一种- def x
- puts \"in x\"
- end
- send :x
复制代码 这也可以调用 x方法,其实send是Object中的一个实例方法,我们说过,能被子类继承。因此我们可直接调用send方法,而这个方法是调用传递过来的x方法名。如果有兴趣看看Object的源码即可理解他的send方法是如何写的。
好了,本次就说到这吧。
注:转载请注明出处。 |
|