在Ruby语言中,super是一个keyword而不是一个方法。
为什么要这样设计呢?
Ruby的设计倾向于实现尽可能多的方法;关键字通常是为具有自己的语法规则的语言功能保留的。然而,super在外观和行为上都像是一个方法调用。
(我知道用纯Ruby语言实现super会很麻烦,因为它必须从caller或use a trace_func中解析出方法名。这本身并不能阻止它成为一种方法,因为很多Kernel的方法都不是用纯Ruby语言实现的。)
发布于 2011-12-11 06:27:54
它的行为有点不同,因为如果你不传递参数,所有当前的参数(如果存在的话,还有块)都会一起传递……我不确定这作为一种方法是如何工作的。
举一个相当做作的例子:
class A
def example(a, b, c)
yield whatever(a, b) + c
end
end
class B < A
def example(a, b, c)
super * 2
end
end我不需要处理收益率,也不需要将参数传递给super。如果您特别想要传递不同的参数,那么它的行为更像是一个方法调用。如果不想传递任何参数,则必须传递空括号(super())。
它与方法调用的行为完全不同。
发布于 2011-12-10 21:16:25
super不会自动调用父类的方法。如果您将拼音类的继承层次结构想象为一个列表,类在底部,Object在顶部,当拼音看到super关键字时,它不仅会检查父类,还会向上移动整个列表,直到找到第一个使用该名称定义了方法的项。
我说item是很小心的,因为它也可以是一个模块。当你在一个类中包含一个模块时,它被包装在一个匿名超类中,并放在我前面提到的列表中的类之上,所以这意味着如果你为你的类定义了一个方法,这个方法也是在模块中定义的,那么从类的实现中调用super将调用模块的实现,而不是父类的实现:
class Foo
def f
puts "Foo"
end
end
module Bar
def f
puts "Bar"
super
end
end
class Foobar < Foo
include Bar
def f
puts "Foobar"
super
end
end
foobar = Foobar.new
foobar.f
# =>
# Foobar
# Bar
# Foo而且我不认为可以从ruby环境本身访问这个‘继承列表’,这意味着这个功能将不可用(无论它有多有用;我不确定这是否是一个预期的功能)。
发布于 2011-12-10 12:40:01
嗯,问得好。我不确定如何(除了使用super)引用给定方法的超级版本。
您不能简单地通过名称调用方法,因为多态性的工作方式(它如何根据对象类确定实际调用该方法的哪个版本)将导致您的方法调用自身,旋转为无限的调用集,并导致堆栈溢出。
https://stackoverflow.com/questions/8454382
复制相似问题