Ruby初心者がイメージで捉える「クラス」

自分でクラスを作ろうとしたときに、クラスとは何なのかよくわからなくなったので、改めて考えてみた。

クラスとは何か?

クラスについて調べると、「クラスとはインスタンスの種類のこと」と書いてあったりする。

正しいのだと思うが、イメージで覚える自分には最初よくわからなかった。特に、クラス自身もオブジェクトである、ということを知ると、「なんで種類がオブジェクト???」と混乱した。

もう一つよく見かける説明が、「クラスとはインスタンスの設計図」というもの。なるほど、設計図ならそれ自体がオブジェクトだというのもわかる。設計図自体もモノだから、いろいろな設計図たちをまとめてClassクラスと呼ぶのか。

オブジェクト(インスタンス)を作るには、クラス名.newをする。しかし、自分のような初心者がよく使う String や Integer や Arrayクラスは、.newを使わずに"apple"[1, 2, 3]のようにして特段クラスを意識せずにオブジェクトを作ることが多いため、クラスの理解がさらに難しくなっている気がする。

(Integerクラスにはnewメソッドがないが、ほとんどのクラスにはある)

クラスとは「製造機」

試行錯誤してたどり着いた自分なりのイメージが、クラスとは「製造機」。

材料を入れてボタンを押すと、オブジェクトが出てくるのだ。

f:id:masuyama13:20200518175846p:plain

String.new("apple")
#=> "apple"

String製造機(Stringクラス)に"apple"を入れてnewボタンを押すと、"apple"というStringオブジェクトが出てくる。

材料の数や入れ方(引数の渡し方)は、クラスごとに決められている。

one = String.new("1")
one.class  # oneのクラス名を調べる
#=> String

String製造機(Stringクラス)に"1"を入れてnewボタンを押すと、"1"というStringオブジェクトが出てくる。"1"は一見 Integer(整数)のようだが、String製造機に入れたものは全てStringオブジェクトとして整えられて出てくる。

ちなみに、String や Array のように、材料を入れなくてもオブジェクトを作れる製造機もある。

String.new
#=> ""
Array.new
#=> []

例で考える

たとえば、以下のようなAreaクラスがあったとする。

newの引数として2つの値をとり、その値を @length と @width というインスタンス変数にそれぞれ代入するというクラスだ。

class Area
  def initialize(length, width)
    @length = length
    @width = width
  end
end

このAreaクラスのインスタンス(オブジェクト)を作ってみる。

area = Area.new(5, 3)

このとき、以下のようなことが起きていると考える。

  1. まず、5 と 3 という2つの値をArea製造機(Areaクラス)に突っ込んで、newボタンを押す。
  2. すると@length = 5@width = 3という属性がセットされたAreaクラスのオブジェクト(インスタンス)が作られて出てくる。
  3. 出てきたAreaクラスのオブジェクトにareaという名前をつける。

areaという名前のオブジェクトのクラス名を調べると、Areaになっていることが確認できる。

area.class  # areaのクラス名を調べる
#=> Area

Classクラスとは何か?

次に、このAreaクラス自体もオブジェクトだというので、Areaクラスというオブジェクトのクラス名を調べてみる。

Area.class  # Areaのクラス名を調べる
#=> Class

Areaクラス自体のクラスはClassクラスだということがわかった。

わかりにくいのでクラスを「製造機」と言い換えると、「Area製造機のクラスはClass製造機」となる。

Classクラスは、いろんなクラス、つまりStringクラスやArrayクラスやAreaクラスなどの種類を表しているのと同時に、いろいろなクラス(= 製造機)自体を作り出すClass製造機のことを表している。