Project1

标题: 【中阶教程】你真的懂了吗?(一) [打印本页]

作者: IamI    时间: 2009-10-6 13:56
标题: 【中阶教程】你真的懂了吗?(一)
本帖最后由 IamI 于 2009-10-7 17:55 编辑

[line]2[/line]
为那些会用脚本但是“不知道怎么就出了个Bug”的人而作。

[line]2[/line]
(一) super
1 super的含义是,执行直接基类中的同名方法
2 super的参数将被直接传递给基类中的同名方法。数量上不符合的,触发ArgumentError
3 如果直接写super,将会把这个方法的参数传递给基类中的同名方法,而不是什么都不传递。
如果写成“super()”,那么什么都不传递。
数量上不符合的,触发ArgumentError。
4 在子类中定义父类的方法,没有super的,父类方法被覆盖。有super的,于该位置执行父类的同名方法
空方法依然可以被super(如【VX】Scene_Base#update),用来进行统一化的基类计算。
5 super不能执行间接基类中的同名方法。如果想跳过直接基类,直接执行间接基类的方法,必须使用alias
6 super是关键字并且具有高优先级。
[line]1[/line]
看不懂?没关系,本来就没希望你看懂= =下面的代码或许可以帮助你理解。如果您无法正常阅读这些代码,那么您还是去加强基本功吧。(喂)
[line]1[/line]
1
  1. class A
  2.   def initialize
  3.     p "call A initialize..."   # 执行 4
  4.   end
  5. end
  6. class B < A
  7.   def initialize
  8.     p "call B initialize..."   # 执行 2
  9.     super                      # 执行 3
  10.   end
  11. end

  12. class C < B
  13.   def initialize
  14.     super                      # 执行 1
  15.     p "call C initialize..."   # 执行 5
  16.   end
  17. end

  18. c = C.new                      # 执行 0
复制代码
应用:规则1、4
这是一张说明脚本运行的流程图……= =

2
  1. class A
  2.   def pass(para)
  3.     p para
  4.   end
  5. end

  6. class B < A
  7.   def pass(para)
  8.     super       # 注意,super没有参数也没有括号,
  9.                 # 应用规则 3(1),参数列直接传给基类
  10.                
  11.     super(para) # 用规则 2 传递参数
  12.     super()     # 用规则 3(2) 传递参数,引发ArgumentError,
  13.                 # 因为提供了 0 个参数给A的pass方法
  14.     # 综上呢……我们还可以说明,一个方法内可以写多个super= =
  15.   end
  16. end  

  17. b = B.new
  18. b.pass("Hello World")
复制代码
应用:规则2、3
是不是很难理解呢那么我们来拿Window_Base做例子吧。(注:下面的脚本必须加在Window_Base定义之后)
3
  1. class Window_A < Window_Base
  2.   def initialize(x,y,width,height)
  3.     super   # 直接传递出本方法的参数(x,y,width,height)
  4.     p "Window_A initialize succeed..."
  5.   end
  6. end

  7. a = Window_A.new(0,0,100,100)

  8. class Window_B < Window_Base
  9.   def initialize(x,y)
  10.     super(x,y,200,200) # 传递自己的2个参数和2个常数
  11.     p "Window_B initialize succeed..."
  12.   end
  13. end

  14. b = Window_B.new(0,0)

  15. # 啥?太简单了?看下面
  16. class Window_C < Window_Base
  17.   def update(a)
  18.     self.contents.draw_text(self.contents.rect,a,1)
  19.     super
  20.   end
  21. end
  22. # c的initialize方法没有重写,也就是Window_Base的
  23. # 所以仍然有 4 个参数
  24. c = Window_C.new(0,0,100,100)
  25. c.update("hi")
复制代码
由于super直接传递了本参数列,所以给了Window_Base的update一个莫名的参数a,于是悲剧。改成super()即可成功刷新。
应用:规则2、3
4【VX】
  1. class Scene_Base
  2.   def start
  3.     p "Scene start..."
  4.   end
  5. end
复制代码
应用:规则4(2)
  1. class A
  2.   def initialize
  3.     p "call A init..."
  4.   end
  5.   def super
  6.     p "call A super..."
  7.   end
  8. end

  9. class B < A
  10.   def initialize
  11.     super
  12.     self.super
  13.   end
  14. end

  15. b = B.new
复制代码
应用:规则6

特别强调说明:以下类的子类,在initialize,update,dispose中必须调用super:
Window/Window_Base
Sprite
Viewport
Plane
Bitmap


家庭作业:看下面代码,预计会出现什么问题或者是通过,并输入查看结果。如果有错误,修改直到无故障。
  1. class Sprite_Up < Sprite
  2.   def initialize(string)
  3.     super()
  4.     @string = string
  5.     self.bitmap = Bitmap.new(640,480)
  6.   end
  7.   def update(str)
  8.     if @string != str
  9.       @string = str
  10.       refresh(str)
  11.     end
  12.   end
  13.   def dispose
  14.   end
  15.   def refresh(str)
  16.     super
  17.     self.bitmap.draw_text(self.bitmap.rect,str)
  18.   end
  19. end

  20. a = Sprite_Up.new("")
  21. for i in 1..300
  22.   a.update("Hello World")
  23.   Graphics.update
  24. end
  25. a.flash(Color.new(255,0,0),40)
  26. for i in 1..40
  27.   Graphics.update
  28. end
  29. a.dispose
复制代码
如果您仍然无法理解,或者家庭作业无法完成,欢迎回帖讨论。
答案在14(孩子你寂寞了口胡)
作者: 赤点    时间: 2009-10-6 14:06
很少看到II写教材,想起我那个坑
作者: 赤点    时间: 2009-10-6 14:17
突然发现我看不懂,ll快教教我
作者: DeathKing    时间: 2009-10-6 14:34
第一感觉像链式反应,第二感觉就是整理了一下,把顺序理清楚了。以前弄super的时候还真没这么麻烦过……现在看了看,还的确真要注意一下。

至于家庭作业么?可能只有7号交了。
作者: 夏季冰川    时间: 2009-10-6 14:37
要睡觉了,明天再来看看。
作者: DeathKing    时间: 2009-10-6 14:39
真囧……把16行的super注释掉结果就鞋盒了?怪哉……把Linux的稿子写完了慢慢研究。
作者: DeathKing    时间: 2009-10-6 17:41
真囧……把16行的super注释掉结果就鞋盒了?怪哉……把Linux的稿子写完了慢慢研究。
DeathKing 发表于 2009-10-6 14:39


是么?那找个时间仔细看看,开始给x档案写稿子,没细看……
作者: dbshy    时间: 2009-10-6 18:36
大姐姐前来支持
作者: 奶油Da蛋糕    时间: 2009-10-6 18:54
先膜拜,再慢慢看。。。。
作者: 奶油Da蛋糕    时间: 2009-10-6 18:56
  1. class Sprite_Up < Sprite
  2.   def initialize(string)
  3.     super()
  4.     @string = string
  5.     self.bitmap = Bitmap.new(640,480)
  6.   end
  7.   def update(str)
  8.     super()
  9.     if @string != str
  10.       @string = str
  11.       refresh(str)
  12.     end
  13.   end
  14.   def dispose
  15.     super
  16.   end
  17.   def refresh(str)
  18.     self.bitmap.draw_text(self.bitmap.rect,str)
  19.   end
  20. end

  21. a = Sprite_Up.new("")
  22. for i in 1..300
  23.   a.update("Hello World")
  24.   Graphics.update
  25. end
  26. a.flash(Color.new(255,0,0),40)
  27. for i in 1..40
  28.   Graphics.update
  29. end
  30. a.dispose
复制代码
这样就算完成了么
太简单了吧,哇哈哈哈。
作者: Eienshinken    时间: 2009-10-6 18:59
好难。。。。。。。。。。。。。。:dizzy:
作者: DeathKing    时间: 2009-10-6 19:50
我还想说一句,论坛设置的图片缩放把Lz的那张图缩得好难看
作者: ★_茄孓    时间: 2009-10-6 20:43
嗯`来顶II哈`
学习学习!!!
作者: IamI    时间: 2009-10-7 13:34
下面公布家庭作业答案:
class Sprite_Up < Sprite
  def initialize(string)
    super()
    @string = string
    self.bitmap = Bitmap.new(640,480)
  end
  def update(str)
    super()
    if @string != str
      @string = str
      refresh(str)
    end
  end
  # dispose
  def refresh(str)
    #super
    self.bitmap.draw_text(self.bitmap.rect,str,1)
  end
end

a = Sprite_Up.new("")
for i in 1..300
  a.update("Hello World")
  Graphics.update
end
a.flash(Color.new(255,0,0),40)
for i in 1..40
  a.update("Hello World")
  Graphics.update
end
a.dispose

refresh中super删去(10分)
dispose方法定义直接删去(15分。加super的得10分)
update要加上super(10分)
最后的循环中,必须更新精灵,否则看不到flash的效果(15分)
另外闲着没事给draw_text加上1得到额外的5分,总分不超过50分。
大家做的如何> <
作者: 夏季冰川    时间: 2009-10-7 14:05
另外闲着没事给draw_text加上1得到额外的5分
IamI 发表于 2009-10-7 13:34

这东西我也注意到了,我很奇怪为啥少了1它不抱错?
作者: 奶油Da蛋糕    时间: 2009-10-7 14:09
这算哪门子答案,这个动画也没动起来呀貌似就改了下坐标。
作者: DeathKing    时间: 2009-10-7 16:28
好像最开始就注释了一个……囧了Orz~

dispose那地方还真没看到……Orz……
作者: 倚乐    时间: 2009-10-17 08:08
提示: 作者被禁止或删除 内容自动屏蔽
作者: 瓦沙尔    时间: 2009-10-31 21:06
提示: 作者被禁止或删除 内容自动屏蔽
作者: づ夏夜の雨    时间: 2009-11-1 14:02
好难,不明白..
作者: 水镜风生    时间: 2009-11-1 14:34
感激,受教了……

本来还一直以为ruby调用函数时没有参数就直接省略(),没想到super和super()还有区别。
跳过直接父类调用间接父类的同名方法也很棒,之前一直没想到还能这样。

至于家庭作业嘛,咳咳,逃掉好了……
作者: 霜冻之狼    时间: 2009-11-1 14:45
我果然是脚本无能……

还是回去学俺的画画去~




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