LoginSignup
1

More than 5 years have passed since last update.

[Ruby] モジュールの include と クラス継承

Last updated at Posted at 2017-07-23

モジュールの include とクラスの 継承 について.
モジュールの include とクラスの 継承 は, それを行うタイミングによって include と 継承 の挙動が変わるのでメモ.

確認環境

  • Ruby v2.3.7p456

パターン[1]: 下位クラスで include と 継承 を行った場合

まずはモジュールと親クラスで同名メソッドが定義されていて, それらを inlude, 継承 した場合の動きを確認する.

モジュール定義とクラス定義

define_module_define_class.rb
# まずはモジュール定義
module Mdl
  def hoge
    puts "hoge is defined by Mdl"
  end
end

# Mdl のメソッドと同名メソッドを定義したクラス
class Cls1
  def hoge
    puts "hoge is defined by Cls1"
  end
end

# Mdl を include し, かつ Cls1 を継承するクラス
class Cls2 < Cls1
  include Mdl
end

継承関係の確認

verify_inheritance.rb
Cls2.ancestors # :=> [Cls2, Mdl, Cls1, Object, Kernel, BasicObject]

挙動の確認

verify_behavior.rb
# hoge は Mdl, Cls1 どちらのメソッドが実行されるか
Cls2.new.hoge # :=> hoge is defined by Mdl

パターン[2]: 上位クラスで include を行った場合

次にモジュールと親クラスで同名メソッドが定義されていて, 親クラスでモジュールを inlude した場合の動きを確認する.

モジュール定義とクラス定義

define_module_define_class2.rb
# まずはモジュール定義
module Mdl
  def hoge
    puts "hoge is defined by Mdl"
  end
end

# Mdl を include し, かつ Mdl のメソッドと同名メソッドを定義したクラス
class Cls1
  include Mdl
  def hoge
    puts "hoge is defined by Cls1"
  end
end

# Cls1 を継承するクラス
class Cls2 < Cls1
end

継承関係の確認

verify_inheritance2.rb
Cls2.ancestors # :=> [Cls2, Cls1, Mdl, Object, Kernel, BasicObject]

挙動の確認

verify_behavior2.rb
# hoge は Mdl, Cls1 どちらのメソッドが実行されるか
Cls2.new.hoge # :=> hoge is defined by Cls1

結論

Cls2.ancestors を行ったときの結果がすべて.
つまり

  • パターン[1]

    • Cls2.ancestors # :⇒ [Cls2, Mdl, Cls1, Object, Kernel, BasicObject]
    • Mdl が継承チェーン上, Cls2 の直上に来ているので, Mdl.hoge が最初に見つかり実行される
  • パターン[2]

    • Cls2.ancestors # :⇒ [Cls2, Cls1, Mdl, Object, Kernel, BasicObject]
    • Cls1 が継承チェーン上, Cls2 の直上に来ているので, Cls1.hoge が最初に見つかり実行される

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
1