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

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

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'?

  1. class Base
  2. def a
  3. puts "hi, this is Base.a"
  4. end
  5. end
  6. class Derived < Base
  7. def a
  8. puts "hi, this is Derived.a"
  9. end
  10. def b
  11. # 这里是我想要调用Base.a的地方
  12. super # 这个工作
  13. end
  14. 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?

  1. class Base
  2. def a
  3. puts &quot;hi, this is Base.a&quot;
  4. end
  5. end
  6. class Derived &lt; Base
  7. def a
  8. puts &quot;hi, this is Derived.a&quot;
  9. end
  10. def b
  11. # here is where I want to call Base.a
  12. Base.a # this doesn&#39;t work
  13. end
  14. end

答案1

得分: 6

你可以使用方法 Method#super_method

  1. class Base
  2. def a
  3. puts "hi, this is Base.a"
  4. end
  5. end
  6. class Derived < Base
  7. def a
  8. puts "hi, this is Derived.a"
  9. end
  10. def b
  11. # 这里我想调用 Base.a
  12. method(:a).super_method.call
  13. end
  14. end
  15. Derived.new.b
  16. hi, this is Base.a

更一般地,你可以有参数和/或一个块:

  1. class Base
  2. def c(x, &block)
  3. puts "ho, this is Base.c"
  4. block.call(3*x)
  5. end
  6. end
  7. class Derived < Base
  8. def c(x, &block)
  9. puts "ho, this is Derived.c"
  10. block.call(x)
  11. end
  12. def d(x, &block)
  13. method(:c).super_method.call(x, &block)
  14. end
  15. end
  16. Derived.new.d(5) { |x| puts "#{x} is a lot" }
  17. ho, this is Base.c
  18. 15 is a lot

你还可以这样做:

  1. class A
  2. def a
  3. "A.a"
  4. end
  5. end
  6. class B < A
  7. def a
  8. "B.a"
  9. end
  10. end
  11. class C<B
  12. def a
  13. "C.a"
  14. end
  15. def test
  16. method(:a).super_method.super_method.call
  17. end
  18. end
  19. C.new.test
  20. # => "A.a"
英文:

You can use the method Method#super_method:

  1. class Base
  2. def a
  3. puts &quot;hi, this is Base.a&quot;
  4. end
  5. end

<!-->
class Derived < Base
def a
puts "hi, this is Derived.a"
end

  1. def b
  2. # here is where I want to call Base.a
  3. method(:a).super_method.call
  4. end
  5. end

<!-->
Derived.new.b
hi, this is Base.a


More generally, you could have arguments and/or a block.

  1. class Base
  2. def c(x, &amp;block)
  3. puts &quot;ho, this is Base.c&quot;
  4. block.call(3*x)
  5. end
  6. end

<!-->
class Derived < Base
def c(x, &block)
puts "ho, this is Derived.c"
block.call(x)
end

  1. def d(x, &amp;block)
  2. method(:c).super_method.call(x, &amp;block)
  3. end
  4. 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.

  1. class A
  2. def a
  3. &quot;A.a&quot;
  4. end
  5. 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

  1. class Base
  2. def a
  3. puts "hi, this is Base.a"
  4. end
  5. end
  6. class Derived < Base
  7. alias_method :base_a, :a
  8. def a
  9. puts "hi, this is Derived.a"
  10. end
  11. def b
  12. base_a
  13. end
  14. end
  1. >> Derived.new.b
  2. hi, this is Base.a
  3. >> Derived.new.a
  4. 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

  1. class Base
  2. def a
  3. puts &quot;hi, this is Base.a&quot;
  4. end
  5. end
  6. class Derived &lt; Base
  7. alias_method :base_a, :a
  8. def a
  9. puts &quot;hi, this is Derived.a&quot;
  10. end
  11. def b
  12. base_a
  13. end
  14. end
  1. &gt;&gt; Derived.new.b
  2. hi, this is Base.a
  3. &gt;&gt; Derived.new.a
  4. 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:

确定