我很难理解什么时候可以调用“超级”,什么时候不能。在下面的示例中,super方法导致无超类错误。
class Bacterium
def eats
puts "Nam"
end
end
class Bacterium
def eats
super # -> no superclass error
puts "Yam"
end
end
b = Bacterium.new
b.eats
但这有效:
class Fixnum
def times
super # -> works
puts "done"
end
end
5.times { |i| puts i.to_s }
5不仅仅是Fixnum的一个实例。我是不是在重新定义现有方法,如上面的细菌例子?
答案 0 :(得分:3)
不,不是真的。 Fixnum
继承自Integer
类,您实际上覆盖了Integer#times
,因此super
可以正常工作,因为它从父级调用实现。
为了在monkeypatching时实现类似的功能,你应该在重新定义之前使用别名方法,并通过别名调用它。
class Bacterium
alias_method :eats_original, :eats
def eats
eats_original # -> "Nam"
puts "Yam"
end
end
类重新开放不是一种继承形式,super
在那里没用。
答案 1 :(得分:3)
正如Mladen所说,您可以使用Class#superclass
检查:
irb> Fixnum.superclass
=> Integer
整数是否实现了#times
?:
irb> Integer.instance_methods.grep /times/
=> [:times]
是的。
因此,以简化的方式,我们可以说,super调用您在超类中的方法。在您的情况下,Bacterium
的超类是Object,它不实现#eats
。
我说这很简单,因为看看这个例子:
module One
def hi
" World" << super()
end
end
module Two
def hi
"Hello" << super()
end
end
class SayHi
def hi
"!!!"
end
end
h = SayHi.new
h.extend(One)
h.extend(Two)
puts h.hi
#=> Hello World!!
不要认真对待我在这里所写的内容,它实际上是Ruby对象模型的冰山一角,这对于理解很重要(我还在学习它) - 那么你将获得大部分或全部概念
使用一些Google-fu作为“Ruby对象模型”......