0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[ Ruby ]クラスのネストや、継承、selfの基礎

Last updated at Posted at 2020-10-11

はじめに

作業しながらも、継承の影響範囲ってどこまでだっけ。。とか
この場合のselfは何を指しているんだっけ。。とか
基礎部分をフワッとしか理解できていなかったので今回は

  • クラス
    • 継承
    • self
    • ネスト

といった内容を、実際に書きながら学んでいったのでその記録として書きます。
メソッドや変数のことも書きたいのですが、長くなりそうなので別で書きたいと思います。

クラスの継承

クラスを定義する際にスーパークラスを1つ指定することができ、
この時に指定しない場合は、自動的にobjectクラスを継承します。
そのため、クラスを新しく定義する時は常に何かのクラスを継承する形になり
必ず継承ツリーのどこかに入ることになります。

継承する対象

  • スーパークラスのクラスメソッド
  • インスタンスメソッド
  • メソッド内に記述されているインスタンス変数

また、継承ではありませんが、スーパークラスの定数、クラス変数も参照できます。

class Klass
  VALUE = "I'm VALUE"
  @@class_val = "I'm class_val"
end

class A < Klass
end

class B < A
  def self.display_bal
    puts @@class_val
  end
end

# スーパークラスの定数の参照
puts B::VALUE
# => I'm VALUE

# クラス変数の継承
B.display_val
# => I'm class_val

self

selfはオブジェクトそのものを指すので、使用する場所によって中身が変わります。

以下の例では、インスタンスメソッド内で使用した場合のみ、インスタンスオブジェクトを指しました。
また、クラスメソッドを定義する際に用いるselfは、クラスオブジェクトを指しているため
self.メソッド名selfを直接クラス名で指定することもできます。

class Klass
  # Klass
  p self
  
  # Klass
  def (p self).class_method
      puts "inner_class_method"  
      # Klass
      p self
  end

  def instance_method
    puts "inner_instance_method"
    # <Klass:0x00007fa07e1a47c8>
    p self
  end
end

Klass.class_method
klass_instanse =  Klass.new
klass_instanse.instance_method

クラスのネストなど

クラスを定義する際に、他のクラスにネストさせることができます。
定義の仕方として以下の2パターンがありますが、一部挙動が変わってきます。

# 直接中に記述する
class TopKlass
  class Klass
  end
end

## ------ ##

# ”::”を用いる
class TopKlass
end

class TopKlass::Klass
end

定義の仕方による挙動の違い

定数の参照

・直接中に記述
自身からトップレベル方向へ順に定数を参照していきます。
自身から近い順にから順に参照していき、最後にトップレベルを参照するという流れになります。

VALUE = "Top level"

class TopKlass
  VALUE = "in TopKlass"

  class InnerKlass
    def self.put_value
      puts VALUE
    end
  end

end

TopKlass::InnerKlass.put_value
# => in TopKlass

・ネームスペースを用いて記述
自身に定数がなければ、次にトップレベルを参照すし、そこから順に自身のクラス方向へ参照していきます。

VALUE = "Top level"

class TopKlass
  VALUE = "in TopKlass"
end

class TopKlass::InnerKlass
  def self.put_value
    puts VALUE
  end
end

TopKlass::InnerKlass.put_value
# => Top level

class,module のどちらにネストさせるのかを明確にする

・中に記述
各階層でclassかmoduleかを指定するため、別で定義したmoduleをclassとして指定するとエラーになります。

module TopKlass
end

class TopKlass
  class InnerKlass
  end
end

# => TopKlass is not a class (TypeError)

・ネームスペースを用いて記述
classかどうかを指定するのは、最後(一番右)に記述したもののみであるため、
それ以外はclassやmoduleの判断を柔軟に行ってくれます。

module TopKlass
end

class TopKlass::InnerKlass
end

# エラーにならない

ネスト元のオブジェクトがなかった時に例外を出すかどうか

・中に記述
以下の例の場合、TopKlassを別で定義していなかった場合、
新たにTopKlassを定義してくれるため例外は発生しません。

class TopKlass
  class InnerKlass
  end
end

・ネームスペースを用いて記述

以下の場合は、別でTopKlassを定義していなかった場合例外を出します。
新たにTopKlassを定義はしてくれません。

class TopKlass::InnerKlass
end

# => uninitialized constant TopKlass (NameError)

おわり

0
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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?