查看完整版本: A.10 面向对象

黑马 2008-7-16 13:24

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方法是如何写的。
好了,本次就说到这吧。
注:转载请注明出处。

[[i] 本帖最后由 黑马 于 2008-8-28 17:21 编辑 [/i]]

黑马 2008-7-26 09:55

怎么没有跟贴?
case(情况)
when  '写的不对':
     puts '请改错'
when  '没听懂':
     puts   '那应该有问题吧'
default :
     puts '下次不打这么多字了'
end

zookeeper53 2008-7-26 10:33

非常受用.支持撒.

alanyuqiang 2008-7-27 02:09

这么好的贴不回复下,对不起楼主了。黑马,“以后不打那么多字了”,可不要啊。你的帖子让人学的都比较有深度。支持你继续

alanyuqiang 2008-7-27 02:30

"任何方法的调用(或叫消息发的送)必须有一个消息的接受者,如果没指定,隐含使用self".
是消息的接收者?不应该是任何方法的调用,都有个它的发送者吗?如:
class AAA
  def one_method
    puts “one_method"
  end
end
aaa=AAA.new
aaa.one_method
这里aaa不是one_method的发送者么?哪里有接收者?望解答

黑马 2008-7-27 08:59

方法调用,如   aaa.one_method
one_method称为消息,aaa称为消息受者.
这里只是说想调用执行one_method方法,那么能取这个名称作为方法名的类太多了,任何一个类都可以,包括对象,模块..都可以取这个名字作为方法名.那到底调用了谁的了?因此就要有个宿主,即称为"消息"接受者,你的例中就是aaa这个对象.

sevk 2008-8-26 10:49

学习中,代码看起来有点难读,希望格式化一下.

weywong 2008-8-26 22:34

instant_method应该是instance_method吧?我说怎么找不到呢。

黑马 2008-8-28 17:19

[quote]原帖由 [i]weywong[/i] 于 2008-8-26 22:34 发表 [url=http://www.ruby-lang.org.cn/forums/redirect.php?goto=findpost&pid=19360&ptid=5664][img]http://www.ruby-lang.org.cn/forums/images/common/back.gif[/img][/url]
instant_method应该是instance_method吧?我说怎么找不到呢。 [/quote]
嗯,打错了.
页: [1]
查看完整版本: A.10 面向对象