如果我有一个带有方法“a”的基类和一个重新实现方法“a”的派生类,我可以通过调用 ; 从 Derived.a 调用superBase.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
# here is where I want to call Base.a
Base.a # this doesn't work
end
end
Run Code Online (Sandbox Code Playgroud)
您可以使用方法Method#super_method:
class Base
def a
puts "hi, this is Base.a"
end
end
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
Derived.new.b
hi, this is Base.a
Run Code Online (Sandbox Code Playgroud)
更一般地说,您可以有参数和/或块。
class Base
def c(x, &block)
puts "ho, this is Base.c"
block.call(3*x)
end
end
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
Derived.new.d(5) { |x| puts "#{x} is a lot" }
ho, this is Base.c
15 is a lot
Run Code Online (Sandbox Code Playgroud)
您还可以执行以下操作。
class A
def a
"A.a"
end
end
Run Code Online (Sandbox Code Playgroud)
class B < A
def a
"B.a"
end
end
Run Code Online (Sandbox Code Playgroud)
class C<B
def a
"C.a"
end
Run Code Online (Sandbox Code Playgroud)
def test
method(:a).super_method.super_method.call
end
end
Run Code Online (Sandbox Code Playgroud)
C.new.test
#=> "A.a"
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
>> Derived.new.b
hi, this is Base.a
>> Derived.new.a
hi, this is Derived.a
Run Code Online (Sandbox Code Playgroud)