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

huangapple go评论63阅读模式
英文:

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 &quot;hi, this is Base.a&quot;
  end

end

class Derived &lt; Base
  def a
    puts &quot;hi, this is Derived.a&quot;
  end

  def b
    # here is where I want to call Base.a
    Base.a  # this doesn&#39;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 &quot;hi, this is Base.a&quot;
  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, &amp;block)
    puts &quot;ho, this is Base.c&quot;
    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, &amp;block)
    method(:c).super_method.call(x, &amp;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
    &quot;A.a&quot;
  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 &quot;hi, this is Base.a&quot;
  end
end

class Derived &lt; Base
  alias_method :base_a, :a

  def a
    puts &quot;hi, this is Derived.a&quot;
  end

  def b
    base_a
  end
end
&gt;&gt; Derived.new.b
hi, this is Base.a
&gt;&gt; Derived.new.a
hi, this is Derived.a

huangapple
  • 本文由 发表于 2023年7月14日 06:47:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76683707.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定