【发布时间】:2013-08-26 16:37:19
【问题描述】:
我已经使用super 来初始化父类,但我看不到任何从子类方法调用父类的方式。
我知道 PHP 和其他语言确实具有此功能,但在 Ruby 中找不到实现此功能的好方法。
在这种情况下人们会怎么做?
【问题讨论】:
标签: ruby
我已经使用super 来初始化父类,但我看不到任何从子类方法调用父类的方式。
我知道 PHP 和其他语言确实具有此功能,但在 Ruby 中找不到实现此功能的好方法。
在这种情况下人们会怎么做?
【问题讨论】:
标签: ruby
如果方法名称相同,即您要覆盖一个方法,您可以简单地使用super。否则,您可以使用 alias_method 或绑定。
class Parent
def method
end
end
class Child < Parent
alias_method :parent_method, :method
def method
super
end
def other_method
parent_method
#OR
Parent.instance_method(:method).bind(self).call
end
end
【讨论】:
Child.new.other_method 返回NoMethodError: super: no superclass method 'other_method' for #<Child:0x007fca161a9400>。对super.method() 的调用只会在调用super 返回的任何内容上调用method(在这种情况下,它不存在)。 super 不是对实例的 superclass 的引用。
super 将使用传递给子方法的确切参数调用 super。如果你想指定参数,你可以通过调用 super 来指定它们:EG:def child(a, b); super; end vs def child(a, b); super(somevar); end
super keyword调用超类中的同名方法:
class Foo
def foo
"#{self.class}#foo"
end
end
class Bar < Foo
def foo
"Super says: #{super}"
end
end
Foo.new.foo # => "Foo#foo"
Bar.new.foo # => "Super says: Bar#foo"
【讨论】:
Ruby 中的super 关键字实际上调用了父类中的同名方法。 (source)
class Foo
def foo
# Do something
end
end
class Bar < Foo
def foo
super # Calls foo() method in parent class
end
end
【讨论】:
其他人已经说得很好。还有一点需要注意:
不支持在超类中调用 foo 方法的语法 super.foo。相反,它将调用super-方法并在返回的结果上尝试调用foo。
class A
def a
"A::a"
end
end
class B < A
def a
"B::a is calling #{super.a}" # -> undefined method `a` for StringClass
end
end
【讨论】:
class Parent
def self.parent_method
"#{self} called parent method"
end
def parent_method
"#{self} called parent method"
end
end
class Child < Parent
def parent_method
# call parent_method as
Parent.parent_method # self.parent_method gets invoked
# call parent_method as
self.class.superclass.parent_method # self.parent_method gets invoked
super # parent_method gets invoked
"#{self} called parent method" # returns "#<Child:0x00556c435773f8> called parent method"
end
end
Child.new.parent_method #This will produce following output
Parent called parent method
Parent called parent method
#<Child:0x00556c435773f8> called parent method
#=> "#<Child:0x00556c435773f8> called parent method"
self.class.superclass == Parent #=> true
Parent.parent_method 和 self.class.superclass 将调用 Parent 的 self.parent_method(类方法) 而
super调用Parent的parent_method(实例方法)。
【讨论】: