Project1

标题: 新手教程——module(模块)的函数传递和类的定义运算符_(9) [打印本页]

作者: 一箭烂YiJL    时间: 2011-4-21 12:12
标题: 新手教程——module(模块)的函数传递和类的定义运算符_(9)
本帖最后由 一箭烂YiJL 于 2011-4-21 15:08 编辑


若想从头学习的同学点此:
第一课、新手教程——基础(YiJL脚本请从此课开始)
课序号:9
作者:一箭烂YiJL
出版社:VX教程出版社
售价:完全免费
VX教程出版社的其它教程

上一课:
super的作用和外界调用类中函数_(8)

序:
很久都没发了,都是因为冷清呢!(不要再讨论这个了= =)。
这一课我要说的是module(模块)的函数(方法)传递,和类的运算符。

正式开始:
我们要让module里定义一个方法,然后用"."符号来传递。
还有要定义一个类的运算符,(包括模块)
C++用"operator 运算符"的方法来定义,那么Ruby又怎么样的呢?

A.module的方法传递

先做一个小实验:
  1. module A
  2.   def tell_5
  3.     p 5
  4.   end
  5. end
  6. A.tell_5     # NoMethodError(失败)
复制代码
这是因为模块的构造很独特,简单的办法:
  1. module A
  2.   def self.tell_5
  3.     p 5
  4.   end
  5. end
  6. A.tell_5     # => 5
复制代码
这样就见成效了。self是伪变量,意思是假名/代替词。
那么定义self.tell_a,外界就能用A.tell_a。(self-->A)
其实这样也行:
  1. module A
  2.   def A.tell_5
  3.     p 5
  4.   end
  5. end
  6. A.tell_5     # => 5
复制代码
那么这样呢:
  1. module A
  2. end

  3. def A.tell_5
  4.   p 5
  5. end

  6. A.tell_5     #依然可以 => 5

复制代码
但是这样不行:
  1. def A.tell_5
  2.   p 5
  3. end

  4. A.tell_5     # Error
复制代码
因为A根本就没定义是啥。

除了这一种外,还有两种办法,但有好处有公开实例变量、alias...(<=这些还没教)所以先不教。



B.运算符的定义

当你想将两个不同/相同的类(class)加、减、乘...(运算起来),
但是他们又不是数字类,但又想将其的某些(实例)变量加起来。

先学个有关的:
  1. class XXX
  2.   
  3.   # 初始化
  4.   def initialize
  5.     @abc = 5
  6.   end
  7.   
  8.   # 修改abc量
  9.   def abc=(value)
  10.     @abc = value
  11.   end
  12.   
  13.   # 返回abc的量
  14.   def abc
  15.     return @abc
  16.   end
  17. end

  18. cc = XXX.new  # .new与initialize相连
  19. p cc.abc      # => 5
  20. cc.abc = 60
  21. p cc.abc      # => 60
复制代码
这个只是最简单的"="号运算符的定义。


来个深奥点的:
  1. class XXX
  2.   
  3.   # 初始化
  4.   def initialize
  5.     @abc = 5
  6.   end
  7.   
  8.   # 返回加完后的abc量 (留意名字变动!)
  9.   def +(value)
  10.     return @abc + value
  11.   end
  12.   
  13. end

  14. cc = XXX.new  # .new与initialize相连
  15. p cc + 50     # => 55
  16. # 怎么不需要用"."来最为传递呢?
  17. # 这是定义运算符的特色,然而有"."也可以:
  18. p cc.+ 50     # => 55
复制代码
那么两个非数字类又怎么做:
  1. class XXX
  2.   
  3.   # 初始化
  4.   def initialize(value)   #(注意变动!)
  5.     @abc = value
  6.   end
  7.   
  8.   # 返回加完后的abc量
  9.   def +(value)
  10.     return @abc + value.abc   #(注意变动!)
  11.   end
  12.   
  13.   # 用于上面的value.abc的接收
  14.   def abc
  15.     return @abc
  16.   end
  17. end

  18. aa = XXX.new(5)   # aa里的@abc为5
  19. bb = XXX.new(8)   # bb里的@abc为8
  20. p aa + bb         # => 5 + 8 = 13
  21. # 关键就在"+value.abc", 所以需要"def abc"来接收这个数字
复制代码
那么不同的类呢?我们只需将".abc"改掉就可以,
不明白的看这里:
  1. class XXX
  2.   
  3.   # 初始化
  4.   def initialize   #(注意变动!)
  5.     @abc = 5
  6.   end
  7.   
  8.   # 返回加完后的abc量
  9.   def +(value)
  10.     return @abc + value.x   #(注意变动!)
  11.   end
  12. end

  13. aa = XXX.new
  14. bb = Rect.new(50, 0, 0, 0)
  15. p aa + bb         # => 5 + 50 = 55
  16. # aa只会加bb的.x, 所以用了"value.x"
  17. # 而bb是Rect(矩形类),其中.x 就是.new的第一个参数(50)
复制代码
好~下课!!!各位同学回个贴~
(反应:同学们都课间休息溜了去玩= =)

作者: summer92    时间: 2011-4-21 14:35
self是类本身?顶吧,谢谢大人,研究研究
作者: 烁灵    时间: 2011-4-21 15:01
本帖最后由 烁灵 于 2011-4-21 15:27 编辑

回复 一箭烂YiJL 的帖子

防止看帖的新手们误解,编辑=w=
作者: DeathKing    时间: 2011-4-22 23:52
Module 的引入初衷,是为了解决多继承问题。 Java 只能单继承,但是通过某种方法可以调和,而 Ruby 使用的混成(Mix-in)机制,就完美的解决了这个问题。
作者: 苏小脉    时间: 2011-4-23 08:53
DeathKing 发表于 2011-4-22 23:52
Module 的引入初衷,是为了解决多继承问题。 Java 只能单继承,但是通过某种方法可以调和,而 Ruby 使用的 ...

Module 同时也提供了一个命名空间。

Java 是类只有单继承,但接口可以多继承,也是解决了钻石问题。
作者: summer92    时间: 2011-4-23 10:59
对对....,当初就觉得和VB命名空间很像...后来竟然忘了,现在才想起来,这样概念又不混淆了,
用  private 所有类都能引用
作者: DeathKing    时间: 2011-4-23 12:59
回复 苏小脉 的帖子

对 Java 了解不深,不过似乎抽象类(abstract classes)和抽象方法可以被继承。
作者: 苏小脉    时间: 2011-4-24 03:12
DeathKing 发表于 2011-4-23 12:59
回复 苏小脉 的帖子

对 Java 了解不深,不过似乎抽象类(abstract classes)和抽象方法可以被继承。 ...

这句话和前文有联系吗?无论是否抽象类,只要是类,在 Java 中就只有单继承。但如果是接口,就可以多继承。
作者: 仲秋启明    时间: 2011-4-24 12:36
剑兰终于出新教程了,支持!
作者: 烁灵    时间: 2011-4-24 12:56
(可以在这一贴请教么0。0


请教前辈
class <<Graphics
……
end

这是什么用法?我定义了一个类么0。0
作者: 一箭烂YiJL    时间: 2011-4-24 13:42
回复 烁灵 的帖子

这是来自我那个XP的旧版(1.0)加速么?

这就是主楼"module的方法传递"说的另外的办法之一,这样定义为特殊类(Singleton Class)。
而主楼这样def A.tell_5已经是是特殊方法/函数(Singleton Method)。
特殊类和特殊方法用在(类的)实例中,但模块本身就跟实例很相近了,
所以特殊方法可被应用在模块。

特殊类的功用和特殊方法的功能很相似,同时也很方便。
XP的旧版加速我本来用这个办法是因为可以用alias,
但是这样定义跟模块的方法定义有功能上的差距。

特殊类和特殊方法未来可能会教到吧~




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