Project1

标题: Ruby细节问题之类和对象等- -bbb [打印本页]

作者: Yurrica    时间: 2007-7-1 15:52
标题: Ruby细节问题之类和对象等- -bbb
    现在我们来介绍下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 进行了编辑]
作者: Yurrica    时间: 2007-7-1 15:52
标题: Ruby细节问题之类和对象等- -bbb
    现在我们来介绍下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 进行了编辑]
作者: 絮儿    时间: 2007-7-1 17:23
{/gg}呃````小夏``~~~~{/hx}
作者: secondsen    时间: 2007-7-1 17:35
还是看得迷迷糊糊的……{/hx}{/hx}{/hx}{/hx}{/hx}{/hx}{/hx}{/hx}
作者: simounF    时间: 2007-7-1 18:17
提示: 作者被禁止或删除 内容自动屏蔽
作者: 神思    时间: 2007-7-1 23:52
原来YUU.....{/fd}{/fd}{/fd}{/fd}
钻洞去````{/shan}
作者: 南宫恋絮    时间: 2007-7-2 00:00
以下引用神思于2007-7-1 15:52:47的发言:

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

哈咻~思思越来越萌鸟{/hx}
作者: 暗之影    时间: 2007-7-2 03:21
提示: 作者被禁止或删除 内容自动屏蔽
作者: 暗之影    时间: 2007-7-2 03:26
提示: 作者被禁止或删除 内容自动屏蔽
作者: 美兽    时间: 2007-7-2 05:10
自从看了JAVA后,发现RUBY与其非常的相似,
以致于在JAVA看到一些东西,
可以在RUBY中搜索差不多的内容,
实际对类等东西之间互相继承与权限的变化一直没怎么明白,
一般是遇到了才去试下。
作者: Yurrica    时间: 2007-7-2 05:18
以下引用神思于2007-7-1 15:52:47的发言:

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

。。。那个8是偶啦。。。{/hx}偶捏思思。。。{/hx}
作者: 星之云    时间: 2007-7-16 22:02
提示: 作者被禁止或删除 内容自动屏蔽
作者: 六脉神剑    时间: 2007-7-17 08:33
以下引用simounF于2007-7-1 10:17:50的发言:
另外发现 %--, %~~, %!! 什么的都可以表示字符串……

%q是字符串 %w是数组,还有些什么%xx的?

%x<cmd> 等同于 `cmd`,也就是执行Shell命令的东西……

另外%q是单引号字符串,在%q中无法使用内嵌表达式;%Q 或者单用 % 都表示双引号字符串
是以两个特殊字符来表示字符串开头和结尾的,比如 %q-开头的话就还得用“-”来结束。还有几个特殊的字符就是(、[、{ 、<,用这几个开头的话就得用相应的)、]、}、>来结束字符串…… >:D

以下引用星之云于2007-7-16 14:02:38的发言:

楼主这个帖子相当好啊,不知道关于这部分内容具体可以在哪里学到,帮助里面好像没这部分内容啊,或许本人看得不够认真,漂过。。。。。。。
问几个问题:
1.  a1.extend B  是不是将a1 跟 模块B 相关联的。
2.  4.3里面的 p A.class_variables  其中class_variables是什么意思,这部分的内容哪里有介绍的?  
3.@@a 跟 @a有什么区别吗?

非常感谢!

1、extend方法将把模块 B 中的实例方法添加到对象a1中,同名的方法将会被覆盖~
2、@@开头的是类变量,@开头的是实例变量,类变量只属于一个类,而不属于一个对象,它的值是静态的,不会因为这个类的不同对象而发生变化……而实例变量在类的每一个对象中都有一份拷贝 o.o

作者: chaochao    时间: 2007-7-17 09:14
3.4、B不能.new生成对象。注意B只能调用B里的模块方法,也就是 self.method_name定义的或module_function声明的那些方法,对于B中的实例方法是给 include和extend用的。
只有类才可以通过new实例化
作者: chaochao    时间: 2007-7-17 09:35
好长时间没碰ruby了.不知到lz一开始说的结构是从哪里弄来的......
作者: Yurrica    时间: 2007-7-17 10:25
以下引用chaochao于2007-7-17 1:35:31的发言:

好长时间没碰ruby了.不知到lz一开始说的结构是从哪里弄来的......

{/hx}脑袋里瞎构思出来的= =b





欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1