glo*_*esk 5 ruby inheritance superclass
我有Boy继承 class 的类Person,并包含 module Bipedal。和Person都有.Bipedal#two_legs
module Bipedal
def two_legs(name)
puts "#{name} has exactly two limbs used for walking."
end
end
class Person
def two_legs(name)
puts "#{name} has two human legs."
end
end
class Boy < Person
include Bipedal
attr_accessor :name
def initialize(name)
@name = name
end
def two_legs
super(@name)
end
end
Run Code Online (Sandbox Code Playgroud)
由于该Bipedal模块包含在 中Boy,Bipedal#two_legs因此优先于Person#two_legs. 当我调用super实例时Boy,模块Bipedal优先于父类Person。
johnny = Boy.new('Johnny')
johnny.two_legs
# >> "Johnny has exactly two limbs used for walking."
Run Code Online (Sandbox Code Playgroud)
我想在一个地方使用一个版本,在另一个地方使用另一个版本。Bipedal还有其他东西,所以我无法评论include Bipedal。是否有一些标准方法可以让Boy#two_legs或super使用父类版本而不是模块版本,如下所示?
johnny.two_legs
# >> "Johnny has two human legs."
Run Code Online (Sandbox Code Playgroud)
我想出了这个:
Boy.superclass.instance_method(:two_legs).bind(self).call(@name)
Run Code Online (Sandbox Code Playgroud)
它可以代替super(@name),但比我预期的更复杂。
再次,问题是,是否有一种标准方法可以强制父类在调用时优先于模块super?
人们可以使用Method#super_method方法两次。这是一种普通的 Ruby 方法,我相信它有资格作为让Boy#two_legsinvokePerson#two_legs而不是Bipedal#two_legs.
class Boy < Person
include Bipedal
attr_accessor :name
def initialize(name)
@name = name
end
def two_legs
method(:two_legs).super_method.super_method.call(@name)
end
end
willie = Boy.new('Willie')
willie.two_legs
Willie has two human legs.
Run Code Online (Sandbox Code Playgroud)
请注意以下事项。
willie.method(:two_legs).super_method.owner
#=> Bipedal
willie.method(:two_legs).super_method.super_method.owner
#=> Person
Run Code Online (Sandbox Code Playgroud)