'супер' и наследование в Ruby - PullRequest
0 голосов
/ 08 мая 2018

В приведенном ниже проекте наследования классов класс B наследует класс A и оценивает аргументы его методов:

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_1 вызывается при вызове B#method_2, а не A#method_1?

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

Я изменил ваш пример, чтобы распечатать текущий класс в A#method_1

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_1, который не принимает аргументов. self в этом случае имеет тип B, а B отменяет method_1, чтобы не принимать аргументов.

Ruby сначала пытается найти метод в self и вызывает его, если он найден, в противном случае он просматривает ancestors этого объекта и вызывает первую версию найденного метода. В вашем случае self имеет method_1, который не принимает аргументов, и помните, что Ruby не поддерживает перегрузку методов (если вы не используете необязательные параметры).

0 голосов
/ 08 мая 2018

method_2 в классе B звонки method_2 (супер) в классе A с аргументом "bar". method_2 в классе A (вызывается из класса B) вызывает method_1 в классе B с аргументом "bar". method_1 и method_2 из класса B переопределяют своих однофамильцев из класса A. Вот почему method_1 из наследуемого класса вызывается.

...