[RUBY] super n'appelle pas seulement les méthodes de la classe parent

introduction

J'étudie pour l'acquisition d'or rubis J'ai changé ma compréhension du super et je voulais le partager.

Sujet principal

Tout d'abord, quel type de résultat sera produit lorsque le code suivant est exécuté?


module M
  def foo
    super
    puts "M#foo"
  end
end

class C2
  def foo
    puts "C2#foo"
  end
end

class C < C2
  def foo
    super
    puts "C#foo"
  end
  include M
end

C.new.foo

Option 1

C2#foo C#foo

Option 2

C2#foo M#foo C#foo

Option 3

L'erreur s'affiche

J'ai toujours pensé que c'était 1. Au fait, la bonne réponse est «option 2» Si vous le comprenez correctement et y répondez correctement, vous n'avez plus besoin de chercher. Merci d'avoir regardé jusqu'à présent.

Tout d'abord, comment ai-je choisi l'option 1

"Méthode foo de classe C, hmm hmm" "Oh, super? Il suffit de regarder la classe des parents foo." "Je vois, la réponse est 1!"

C'est comme ça. Je pensais qu'il ne serait pas appelé lorsque j'ai inclus le module.

Apprenons à connaître la super classe. Tout d'abord, une brève description de super décrit dans le Manuel de référence

super appelle la méthode que la méthode actuelle remplace

Je vois, cela ne semble pas appeler une méthode de superclasse. Utilisons maintenant la méthode des ancêtres.

##réduction

class C < C2
  def foo
    super
    puts "C#foo"
  end
  include M
  self.ancestors #=> [C, M, C2, Object, Kernel, BasicObject]
end

C.new.foo

ancêtres est une méthode qui montre l'ordre de recherche des méthodes de manière simple. Par exemple, lorsque la méthode foo est exécutée, la méthode C foo est recherchée, et sinon, le M foo ... est recherché.

Maintenant, regardons à nouveau le code en question.

module M
  def foo
    super #Se référer à foo dans C2
    puts "M#foo"
  end
end

class C2
  def foo
    puts "C2#foo"
  end
end

class C < C2
  def foo
    super #Se référer au toto de M
    puts "C#foo"
  end
  include M
  self.ancestors #=> [C, M, C2, Object, Kernel, BasicObject]
end

C.new.foo
#=> C2#foo
#=> M#foo
#=> C#foo

Conclusion

en conclusion

Si vous étudiez pour des qualifications, vous approfondirez votre compréhension, donc si vous avez peu d'expérience pratique, vous pouvez essayer d'étudier.

Recommended Posts

super n'appelle pas seulement les méthodes de la classe parent
Diverses méthodes de la classe String
Nommer et appeler explicitement des méthodes de classe parent dans Ruby
Comment se moquer de certaines méthodes de la classe testée
Appelez la super méthode en Java
[Ruby] Résumé des définitions de classe. Maîtrisez les bases.
À propos de next () et nextLine () de la classe Scanner
Première touche de la classe Files (ou Java 8)