3
2

More than 3 years have passed since last update.

Rubyの多重継承優先順位まとめ

Posted at

はじめに

言語の基本的な動作を確認する作業って、ついサボってしまうことが多いのですが、今回は職場の先輩に時間を頂いて
あらためてRubyで多重継承に伴うメソッドの呼び出され方を検証しました。

Rubyはクラスの多重継承ができない言語ですが、Moduleを用いて事実上の多重継承を可能にしています(Mixin方式)

ケース1:複数のModuleを継承

module Foo
  def do_task
    puts "I'm in Foo class!"
  end
end

module Bar
  def do_task
    puts "I'm in Bar class!"
  end
end

class Child
  include Foo
  include Bar

  def execute
    do_task
  end
end

instance = Child.new
instance.execute # which task is called?

結果:後勝ち

$ ruby case1.rb
I'm in Bar class!

ケース2:親クラス継承+Module取り込み

module Foo
  def do_task
    puts "I'm in Foo class!"
  end
end

module Bar
  def do_task
    puts "I'm in Bar class!"
  end
end

class Parent
  def do_task
    puts "I'm in the Parent class!"
  end
end

class Child < Parent
  include Foo
  include Bar

  def execute1
    do_task
  end

  def do_task
    super
  end
end

instance = Child.new
instance.execute1 # which task is called?
instance.do_task # which task is called?

結果:取り込むModuleの後勝ち

$ ruby case2.rb
I'm in Bar class!
I'm in Bar class!

ケース3:菱形継承(ダイヤモンド継承)

module Parent
  def do_task
    puts "I'm in the Parent class!"
  end
end

module Foo
  include Parent
end

module Bar
  include Parent
end

class Child
  include Foo
  include Bar

  def execute
    do_task
  end
end

instance = Child.new
instance.execute # which task is called?

結果:問題なく実行可能

$ ruby case3.rb
I'm in the Parent class!

まとめ

というわけで、Rubyではダイヤモンド継承にまつわる問題も回避できていること、基本的には後に書かれたものがオーバーライドするという挙動を確認しました。

複雑なコードでは随所に継承やModuleの取り込みを行いますので、このような基本的コードで挙動を検証するのもたまにはいいかもしれませんね。

多重継承については、Wikipediaでも一定量の知識を習得できるので、CSバックグラウンドがない方やエンジニアになりたての方はあらためて確認してみても良いかもしれません

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2