JQ Blog

Rubyの継承とinclude、extendの使い方

Rubyはオブジェクト指向言語であるのだけれど、Javaや他の言語の継承と考え方、方法が違うので調べてみた

継承

普通にSubクラスに親クラスを継承したら親クラスのメソッドを使えるようになる

1
2
3
4
5
class MyName
  def my_name
    p "My name is Jo"
  end
end
1
2
class Introduction < MyName
end
1
2
3
4
> introduction = Introduction.new
> introduction.my_name

"My name is Jo"

Subクラスが親クラスのメソッドをoverrideすると同じように親クラスのメソッドを使える

1
2
3
4
5
class Introduction < MyName
  def my_name
    super
  end
end
1
2
3
4
> introduction = Introduction.new
> introduction.my_name

"My name is Jo"

Subクラスでoverrideした親クラスのメソッドにsuperを書かないと親クラスからの影響はされない

1
2
3
4
5
class Introduction < MyName
  def my_name
    p "My name is..."
  end
end
1
2
3
4
> introduction = Introduction.new
> introduction.my_name

"My name is..."

だが、上のメソッドにsuperを入れたら

1
2
3
4
5
6
class Introduction < MyName
  def my_name
    p "My name is..."
    super
  end
end
1
2
3
4
5
> introduction = Introduction.new
> introduction.my_name

"My name is..."
"My name is Jo"

include

includeはクラスにモジュールを使うようにしてくれる
継承の場合と少し似ている
まず、普通にクラスにモジュールを継includeしたらモジュールのメソッドを使えるようになる

1
2
3
4
5
module MyAge
  def my_age
    p "My age is 30."
  end
end
1
2
3
class Introduction
  include MyAge
end
1
2
3
4
> introduction = Introduction.new
> introduction.my_name

"My age is 30."

overrideしたクラスのメソッドにsuperをつけると同じようにモジュールのメソッドを使えるようになる

1
2
3
4
5
6
7
class Introduction
  include MyAge

  def my_age
    super
  end
end
1
2
3
4
> introduction = Introduction.new
> introduction.my_name

"My age is 30."

superを書かない場合はモジュールに影響されない

1
2
3
4
5
6
7
class Introduction
  include MyAge

  def my_age
    p "My age is....."
  end
end
1
2
3
4
> introduction = Introduction.new
> introduction.my_name

"My age is....."

その上、superを書いたらクラスのメソッドの処理とモジュールのメソッドの処理が両方行われる

1
2
3
4
5
6
7
8
class Introduction
  include MyAge

  def my_age
    p "My age is....."
    super
  end
end
1
2
3
4
5
> introduction = Introduction.new
> introduction.my_name

"My age is....."
"My age is 30."

extend

extendの使い方はさっきの継承やincludeと少し違う

1
2
3
4
5
module MyHobby
  def my_hobby
    p "My hobby is read a book!"
  end
end
1
2
3
class Introduction
  extend MyHobby
end

モジュールをextendしてクラスをオブジェクト化してメソッドを実行しようとすると NoMethodErrorが出てくる

1
2
3
4
> introduction = Introduction.new
> introduction.my_hobby

NoMethodError: undefined method `my_hobby' for #<Introduction:0x007fd74c0cae38>

だが、次のようにしてみると通る

1
2
3
> Introduction.my_hobby

"My hobby is read a book!"

つまり、extendしたモジュールのメソッドはクラスメソッドのように使えるということ

1
2
3
4
5
6
7
8
class Introduction
  extend MyHobby

  def self.my_hobby
    p "My hobby is....."
    super
  end
end
1
2
3
4
> Introduction.my_hobby

"My hobby is....."
"My hobby is read a book!"

extendはクラスメソッドに影響する

参考

継承, mix-in, include, extend について覚え書き
superを使って継承/Include/Extendしたメソッドをオーバーライド
rubyのrequire/include/extend/継承/クラス拡張ミックスインまとめ