在 Ruby 中,如何从派生类中重写同一方法的不同方法调用基类方法?

Jay*_*Jay 3 ruby

如果我有一个带有方法“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)

Car*_*and 6

您可以使用方法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)


Ale*_*lex 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
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)