设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 4692|回复: 15
打印 上一主题 下一主题

Ruby细节问题之类和对象等- -bbb

 关闭 [复制链接]

Lv1.梦旅人

Duo是偶的~!

梦石
0
星屑
48
在线时间
16 小时
注册时间
2006-4-4
帖子
1708

第1届RMTV比赛季军

跳转到指定楼层
1
发表于 2007-7-1 15:52:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
    现在我们来介绍下Ruby的类和对象以及模块等。= =bb  什么,这也值得介绍么,找PIA- -bb 咳咳,8过我们要介绍的内容就是这些,包括Ruby中的一些特殊类的层次关系等,主要有obj(对象)、class(用户定义的类)、module(用户定义的模块)、Class类、Module类以及Object类。如果你已经很熟悉这些了的话,那么就没必要往下看了。如果发现有什么讲的8对的地方请给予指正 - -bbb{/hx} 好了,现在进入正题,大家先保持清晰的头脑- -bbb{/gg}

问:
class A
end
a = A.new
a.class.class.superclass.superclass == a.class.superclass 吗?

1、先看看总体结构关系好了- -b


2、看了之后大家明白多少了呢- -?米看懂的话也8急,容偶慢慢解释到= = 不过前面提的那个问题应该大概知道了吧{/gg}{/gg}

  首先,对于Class类,这个被大家叫做类的类是Module这个类的子类,而Module这个类又是Object类的子类,ms是废话- -bb。
  其次,我们知道A就是Class类的一个对象,如果你对于A也是一个对象不清楚的话,那么就再翻翻F1看看吧 - -b,这也就是说我们在脚本编辑器里定义一个类的时候也是在操作一个对象,就像我们很熟悉的操作a这个对象一样。很显然的,一个对象就可以调用该对象的类里的实例方法,那么我们在书写类的时候用到了些什么方法呢?最常用的就是attr_accessor、attr_reader这些了,这些就是Class类里的方法,不过这些方法是从Module类里继承下来的。至于到底有些什么用,我们后面再举例说明。
   对于B类,很显然就是Module类的对象了,我们定义模块的时候也是在操作一个对象。
   对于A:include B,也就是使用mix-in实现类似java的接口那些了,即把B中的方法包含到A里面去。对于a.extend B也一样,不同的是现在只增加了a这一个对象的方法,而不是A里的方法。
  
3、现在说说该注意的细节问题:
  3.1、a仅仅是一个对象而已(废话);
  3.2、A即是一个对象,也是一个类;
  3.3、B只是对象,这点和a一样,但大部分功能却和A相同。
  3.4、B不能.new生成对象。注意B只能调用B里的模块方法,也就是 self.method_name定义的或module_function声明的那些方法,对于B中的实例方法是给 include和extend用的。

4、了解清楚这些层次结构后有什么用呢,当然是更清楚的认识程序的逻辑、作用域什么的了。
4.1、
  1. module B
  2.   def b_im
  3.     p 'b_im'
  4.   end
  5.   def self.b_mm
  6.     p 'b_mm'
  7.   end
  8. end

  9. class A
  10.   def a_im
  11.     p 'a_im'
  12.   end
  13.   def self.a_cm
  14.     p 'a_cm'
  15.   end
  16. end
  17. a1 = A.new
  18. a1.extend B
  19. a2 = A.new

  20. #B.b_im # 错误
  21. B.b_mm
  22. #A.a_im # 错误
  23. A.a_cm
  24. a1.b_im
  25. #a1.b_mm # 错误
  26. a1.a_im
  27. #a1.a_cm # 错误

  28. #a2.b_im # 错误
  29. #a2.b_mm # 错误
  30. a2.a_im
  31. #a2.a_cm # 错误
复制代码

对于这段代码,显然a1和a2对象的方法不完全相同。就是a1.extend B的缘故。这些都是很简单的,下面我们说几个比较不常用的。

4.2、
既然我们知道了定义类的时候可以调用Class里的方法,那么我们那写个试试= =

  1. class Class
  2.   
  3.   def attr_flag(*args)
  4.     args.each do |sym|
  5.       class_eval %{
  6.         def #{sym}?
  7.           @#{sym}
  8.         end
  9.         def #{sym}=(value)
  10.           if value != true and value != false
  11.             raise TypeError,"Not a valid value。"
  12.           end
  13.           @#{sym} = value
  14.         end
  15.       }
  16.     end
  17.   end
  18.   
  19. end

  20. class A
  21.   attr_flag :inslg
  22.   def initialize
  23.     @inslg = true
  24.   end
  25. end

  26. a = A.new
  27. p a.inslg?
  28. a.inslg = false
  29. p a.inslg?
复制代码

这里我们在Class类里定义了个attr_flag的方法,我们知道attr_accessor 是定义可写可读的变量的,我们这这里定义了个方法attr_flag专门用于定义那些标记变量。= =bb

4.3、关于ruby的类变量,我们知道在其他语言里类变量都可以直接根据 类名::变量名 的形式访问,但ruby里却不行,那我们定义代码如下:
  1. class Class
  2.   
  3.   def define_cv(name,init = nil)
  4.     class_eval %{
  5.       @@#{name} = init
  6.       def self.#{name}
  7.         @@#{name}
  8.       end
  9.       def self.#{name}=(value)
  10.         @@#{name} = value
  11.       end
  12.     }
  13.   end
  14.   
  15. end

  16. class A
  17.   define_cv :nums,0
  18. end

  19. p A.class_variables
  20. p A.nums
  21. A.nums += 1
  22. p A.nums
复制代码

现在我们在定义类的时候可以用 define_cv来声明类变量,第一个参数是名字,第二个参数是初始值,因为类变量是必须初始化的。当然省略第二个参数的时候我们默认为nil。

例子就不举了,还有很多作用,留几个问题给大家探讨好了:
1、分清这三个变量分别可以被那些访问
class A
  @@a = 1
  @b = 2
  def initialize
    @c = 3
  end
end

2、以下这几种形式哪个可以得到a.a等于1:
  1. class A
  2.   def self.new
  3.     @a = 1
  4.   end
  5. end

  6. class A
  7.   def self.new
  8.     super
  9.     @a = 1
  10.   end
  11. end

  12. class A
  13.   attr_reader :a
  14.   def self.new
  15.     @a = 1
  16.     super
  17.   end
  18.   def initialize
  19.     @a = 1
  20.   end
  21. end

  22. class A
  23.   attr_reader :a
  24.   def self.new
  25.     obj = super
  26.     @a = 1
  27.     obj
  28.   end
  29. end
复制代码



3、下面这个和4.3那个有什么区别
class Class
  attr_accessor :obj
end
class A
end
A.obj = 3
p A.obj

{/gg}{/gg}{/gg}先闪- -


              [本贴由 叶舞枫 于 2007-7-16 10:52:07 进行了编辑]

Lv1.梦旅人

Duo是偶的~!

梦石
0
星屑
48
在线时间
16 小时
注册时间
2006-4-4
帖子
1708

第1届RMTV比赛季军

2
 楼主| 发表于 2007-7-1 15:52:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
    现在我们来介绍下Ruby的类和对象以及模块等。= =bb  什么,这也值得介绍么,找PIA- -bb 咳咳,8过我们要介绍的内容就是这些,包括Ruby中的一些特殊类的层次关系等,主要有obj(对象)、class(用户定义的类)、module(用户定义的模块)、Class类、Module类以及Object类。如果你已经很熟悉这些了的话,那么就没必要往下看了。如果发现有什么讲的8对的地方请给予指正 - -bbb{/hx} 好了,现在进入正题,大家先保持清晰的头脑- -bbb{/gg}

问:
class A
end
a = A.new
a.class.class.superclass.superclass == a.class.superclass 吗?

1、先看看总体结构关系好了- -b


2、看了之后大家明白多少了呢- -?米看懂的话也8急,容偶慢慢解释到= = 不过前面提的那个问题应该大概知道了吧{/gg}{/gg}

  首先,对于Class类,这个被大家叫做类的类是Module这个类的子类,而Module这个类又是Object类的子类,ms是废话- -bb。
  其次,我们知道A就是Class类的一个对象,如果你对于A也是一个对象不清楚的话,那么就再翻翻F1看看吧 - -b,这也就是说我们在脚本编辑器里定义一个类的时候也是在操作一个对象,就像我们很熟悉的操作a这个对象一样。很显然的,一个对象就可以调用该对象的类里的实例方法,那么我们在书写类的时候用到了些什么方法呢?最常用的就是attr_accessor、attr_reader这些了,这些就是Class类里的方法,不过这些方法是从Module类里继承下来的。至于到底有些什么用,我们后面再举例说明。
   对于B类,很显然就是Module类的对象了,我们定义模块的时候也是在操作一个对象。
   对于A:include B,也就是使用mix-in实现类似java的接口那些了,即把B中的方法包含到A里面去。对于a.extend B也一样,不同的是现在只增加了a这一个对象的方法,而不是A里的方法。
  
3、现在说说该注意的细节问题:
  3.1、a仅仅是一个对象而已(废话);
  3.2、A即是一个对象,也是一个类;
  3.3、B只是对象,这点和a一样,但大部分功能却和A相同。
  3.4、B不能.new生成对象。注意B只能调用B里的模块方法,也就是 self.method_name定义的或module_function声明的那些方法,对于B中的实例方法是给 include和extend用的。

4、了解清楚这些层次结构后有什么用呢,当然是更清楚的认识程序的逻辑、作用域什么的了。
4.1、
  1. module B
  2.   def b_im
  3.     p 'b_im'
  4.   end
  5.   def self.b_mm
  6.     p 'b_mm'
  7.   end
  8. end

  9. class A
  10.   def a_im
  11.     p 'a_im'
  12.   end
  13.   def self.a_cm
  14.     p 'a_cm'
  15.   end
  16. end
  17. a1 = A.new
  18. a1.extend B
  19. a2 = A.new

  20. #B.b_im # 错误
  21. B.b_mm
  22. #A.a_im # 错误
  23. A.a_cm
  24. a1.b_im
  25. #a1.b_mm # 错误
  26. a1.a_im
  27. #a1.a_cm # 错误

  28. #a2.b_im # 错误
  29. #a2.b_mm # 错误
  30. a2.a_im
  31. #a2.a_cm # 错误
复制代码

对于这段代码,显然a1和a2对象的方法不完全相同。就是a1.extend B的缘故。这些都是很简单的,下面我们说几个比较不常用的。

4.2、
既然我们知道了定义类的时候可以调用Class里的方法,那么我们那写个试试= =

  1. class Class
  2.   
  3.   def attr_flag(*args)
  4.     args.each do |sym|
  5.       class_eval %{
  6.         def #{sym}?
  7.           @#{sym}
  8.         end
  9.         def #{sym}=(value)
  10.           if value != true and value != false
  11.             raise TypeError,"Not a valid value。"
  12.           end
  13.           @#{sym} = value
  14.         end
  15.       }
  16.     end
  17.   end
  18.   
  19. end

  20. class A
  21.   attr_flag :inslg
  22.   def initialize
  23.     @inslg = true
  24.   end
  25. end

  26. a = A.new
  27. p a.inslg?
  28. a.inslg = false
  29. p a.inslg?
复制代码

这里我们在Class类里定义了个attr_flag的方法,我们知道attr_accessor 是定义可写可读的变量的,我们这这里定义了个方法attr_flag专门用于定义那些标记变量。= =bb

4.3、关于ruby的类变量,我们知道在其他语言里类变量都可以直接根据 类名::变量名 的形式访问,但ruby里却不行,那我们定义代码如下:
  1. class Class
  2.   
  3.   def define_cv(name,init = nil)
  4.     class_eval %{
  5.       @@#{name} = init
  6.       def self.#{name}
  7.         @@#{name}
  8.       end
  9.       def self.#{name}=(value)
  10.         @@#{name} = value
  11.       end
  12.     }
  13.   end
  14.   
  15. end

  16. class A
  17.   define_cv :nums,0
  18. end

  19. p A.class_variables
  20. p A.nums
  21. A.nums += 1
  22. p A.nums
复制代码

现在我们在定义类的时候可以用 define_cv来声明类变量,第一个参数是名字,第二个参数是初始值,因为类变量是必须初始化的。当然省略第二个参数的时候我们默认为nil。

例子就不举了,还有很多作用,留几个问题给大家探讨好了:
1、分清这三个变量分别可以被那些访问
class A
  @@a = 1
  @b = 2
  def initialize
    @c = 3
  end
end

2、以下这几种形式哪个可以得到a.a等于1:
  1. class A
  2.   def self.new
  3.     @a = 1
  4.   end
  5. end

  6. class A
  7.   def self.new
  8.     super
  9.     @a = 1
  10.   end
  11. end

  12. class A
  13.   attr_reader :a
  14.   def self.new
  15.     @a = 1
  16.     super
  17.   end
  18.   def initialize
  19.     @a = 1
  20.   end
  21. end

  22. class A
  23.   attr_reader :a
  24.   def self.new
  25.     obj = super
  26.     @a = 1
  27.     obj
  28.   end
  29. end
复制代码



3、下面这个和4.3那个有什么区别
class Class
  attr_accessor :obj
end
class A
end
A.obj = 3
p A.obj

{/gg}{/gg}{/gg}先闪- -


              [本贴由 叶舞枫 于 2007-7-16 10:52:07 进行了编辑]

Lv1.梦旅人

Dancer-Ne

梦石
0
星屑
50
在线时间
62 小时
注册时间
2006-7-29
帖子
1017
3
发表于 2007-7-1 17:23:19 | 只看该作者
{/gg}呃````小夏``~~~~{/hx}
最近好愛漢服啊~
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
60
在线时间
61 小时
注册时间
2006-9-15
帖子
946
4
发表于 2007-7-1 17:35:15 | 只看该作者
还是看得迷迷糊糊的……{/hx}{/hx}{/hx}{/hx}{/hx}{/hx}{/hx}{/hx}
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
50
在线时间
0 小时
注册时间
2006-11-21
帖子
240
5
发表于 2007-7-1 18:17:50 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

Lv1.梦旅人

彩色的银子

梦石
0
星屑
50
在线时间
190 小时
注册时间
2006-6-13
帖子
1361

贵宾

6
发表于 2007-7-1 23:52:47 | 只看该作者
原来YUU.....{/fd}{/fd}{/fd}{/fd}
钻洞去````{/shan}
-.-
回复 支持 反对

使用道具 举报

Lv1.梦旅人

思絮

梦石
0
星屑
50
在线时间
698 小时
注册时间
2006-3-5
帖子
2585

贵宾

7
发表于 2007-7-2 00:00:20 | 只看该作者
以下引用神思于2007-7-1 15:52:47的发言:

原来YUU.....
钻洞去````

哈咻~思思越来越萌鸟{/hx}
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

脚本盲

梦石
0
星屑
50
在线时间
0 小时
注册时间
2005-11-17
帖子
1753
8
发表于 2007-7-2 03:21:50 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

脚本盲

梦石
0
星屑
50
在线时间
0 小时
注册时间
2005-11-17
帖子
1753
9
发表于 2007-7-2 03:26:05 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

Lv1.梦旅人

月下可怜人

梦石
0
星屑
50
在线时间
10 小时
注册时间
2005-11-23
帖子
4085

第1届短篇游戏比赛亚军

10
发表于 2007-7-2 05:10:56 | 只看该作者
自从看了JAVA后,发现RUBY与其非常的相似,
以致于在JAVA看到一些东西,
可以在RUBY中搜索差不多的内容,
实际对类等东西之间互相继承与权限的变化一直没怎么明白,
一般是遇到了才去试下。
纵然千里外,我等雁归来。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-22 12:27

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表