英文:
In Ruby how do I call a base class method from a different method in a derived class that overrides that same method?
问题
如果我有一个具有方法'a'的基类和一个派生类,该派生类重新实现了方法'a',我可以通过只调用super
来从Derived.a中调用Base.a;如何从不同的派生类方法中调用基类'a'?
class Base
def a
puts "hi, this is Base.a"
end
end
class Derived < Base
def a
puts "hi, this is Derived.a"
end
def b
# 这里是我想要调用Base.a的地方
super # 这个工作
end
end
英文:
If I have a base class with method 'a' and a derived class that reimplements method 'a', I can call Base.a from Derived.a by just calling super
; how do I call the base class 'a' from a different derived class method?
class Base
def a
puts "hi, this is Base.a"
end
end
class Derived < Base
def a
puts "hi, this is Derived.a"
end
def b
# here is where I want to call Base.a
Base.a # this doesn't work
end
end
答案1
得分: 6
你可以使用方法 Method#super_method:
class Base
def a
puts "hi, this is Base.a"
end
end
class Derived < Base
def a
puts "hi, this is Derived.a"
end
def b
# 这里我想调用 Base.a
method(:a).super_method.call
end
end
Derived.new.b
hi, this is Base.a
更一般地,你可以有参数和/或一个块:
class Base
def c(x, &block)
puts "ho, this is Base.c"
block.call(3*x)
end
end
class Derived < Base
def c(x, &block)
puts "ho, this is Derived.c"
block.call(x)
end
def d(x, &block)
method(:c).super_method.call(x, &block)
end
end
Derived.new.d(5) { |x| puts "#{x} is a lot" }
ho, this is Base.c
15 is a lot
你还可以这样做:
class A
def a
"A.a"
end
end
class B < A
def a
"B.a"
end
end
class C<B
def a
"C.a"
end
def test
method(:a).super_method.super_method.call
end
end
C.new.test
# => "A.a"
英文:
You can use the method Method#super_method:
class Base
def a
puts "hi, this is Base.a"
end
end
<!-->
class Derived < Base
def a
puts "hi, this is Derived.a"
end
def b
# here is where I want to call Base.a
method(:a).super_method.call
end
end
<!-->
Derived.new.b
hi, this is Base.a
More generally, you could have arguments and/or a block.
class Base
def c(x, &block)
puts "ho, this is Base.c"
block.call(3*x)
end
end
<!-->
class Derived < Base
def c(x, &block)
puts "ho, this is Derived.c"
block.call(x)
end
def d(x, &block)
method(:c).super_method.call(x, &block)
end
end
<!-->
Derived.new.d(5) { |x| puts "#{x} is a lot" }
ho, this is Base.c
15 is a lot
You could also do the following.
class A
def a
"A.a"
end
end
<!-->
class B < A
def a
"B.a"
end
end
<!-->
class C<B
def a
"C.a"
end
<!-->
def test
method(:a).super_method.super_method.call
end
end
<!-->
C.new.test
#=> "A.a"
答案2
得分: 6
alias_method
可以做到这一点:
使
new_name
成为old_name
方法的新副本。这可用于保留对被覆盖的方法的访问。
https://rubyapi.org/3.2/o/module#method-i-alias_method
class Base
def a
puts "hi, this is Base.a"
end
end
class Derived < Base
alias_method :base_a, :a
def a
puts "hi, this is Derived.a"
end
def b
base_a
end
end
>> Derived.new.b
hi, this is Base.a
>> Derived.new.a
hi, this is Derived.a
英文:
alias_method
can do it:
> Makes new_name a new copy of the method old_name. This can be used to retain access to methods that are overridden.
https://rubyapi.org/3.2/o/module#method-i-alias_method
class Base
def a
puts "hi, this is Base.a"
end
end
class Derived < Base
alias_method :base_a, :a
def a
puts "hi, this is Derived.a"
end
def b
base_a
end
end
>> Derived.new.b
hi, this is Base.a
>> Derived.new.a
hi, this is Derived.a
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论