'super' 和 Ruby 中的继承

'super' and inheritance in Ruby

在下面的class继承设计中,classB继承classA,并计算其方法的参数:

class A
  def method_1(arg)
     puts "Using method_1 with argument value '#{arg}'"
  end

  def method_2(arg)
     method_1(arg)
  end
end

class B < A
   def method_1()
      super("foo")
   end

   def method_2()
      super("bar")
   end
end

这是我尝试时得到的结果:

inst_A = A.new
inst_A.method_1("foo")
# >> Using method_1 with argument value 'foo'
inst_A.method_2("bar")
# >> Using method_1 with argument value 'bar'

我不再理解这个:

inst_B = B.new
inst_B.method_1
# >> Using method_1 with argument value 'foo'
inst_B.method_2
# >> Error: #<ArgumentError: wrong number of arguments (1 for 0)>
# >> <main>:11:in `method_1'
# >> <main>:6:in `method_2'
# >> <main>:16:in `method_2'

为什么在调用 B#method_2 时调用 B#method_1 而不是 A#method_1

method_2 in class B 使用参数 "bar" 在 class A 中调用 method_2(super)。 method_2 in class A(从 class B 调用)使用 arg 在 class B 中调用 method_1 "bar"method_1method_2 来自 class B 覆盖他们来自 class A 的同名。这就是为什么调用继承 class 的 method_1 的原因。

我修改了你的示例以在 A#method_1

中打印出当前 class
def method_1(arg)
   puts "Using method_1 from class: '#{self.class}' with argument value '#{arg}'"
end

如果你调用 B#method_1,你会得到这个输出

Using method_1 from class: 'B' with argument value 'foo'

如您所说,它正在调用 B#method_1(覆盖 A#method_1)。这同样适用于 B#method_2 调用 super,然后尝试调用不带参数的 self#method_1self 在这种情况下是 B 类型,并且 B 覆盖 method_1 不接受任何参数。

Ruby 首先尝试在 self 中找到方法并在找到时调用它,否则它会遍历该对象的 ancestors 并调用它找到的方法的第一个版本.在你的情况下 selfmethod_1 没有参数,请记住 Ruby 不支持方法重载(除非你使用可选参数)。