自分でクラスを作ろうとしたときに、クラスとは何なのかよくわからなくなったので、改めて考えてみた。
クラスとは何か?
クラスについて調べると、「クラスとはインスタンスの種類のこと」と書いてあったりする。
正しいのだと思うが、イメージで覚える自分には最初よくわからなかった。特に、クラス自身もオブジェクトである、ということを知ると、「なんで種類がオブジェクト???」と混乱した。
もう一つよく見かける説明が、「クラスとはインスタンスの設計図」というもの。なるほど、設計図ならそれ自体がオブジェクトだというのもわかる。設計図自体もモノだから、いろいろな設計図たちをまとめてClassクラスと呼ぶのか。
オブジェクト(インスタンス)を作るには、クラス名.new
をする。しかし、自分のような初心者がよく使う String や Integer や Arrayクラスは、.new
を使わずに"apple"
や[1, 2, 3]
のようにして特段クラスを意識せずにオブジェクトを作ることが多いため、クラスの理解がさらに難しくなっている気がする。
(Integerクラスにはnewメソッドがないが、ほとんどのクラスにはある)
クラスとは「製造機」
試行錯誤してたどり着いた自分なりのイメージが、クラスとは「製造機」。
材料を入れてボタンを押すと、オブジェクトが出てくるのだ。
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)
このとき、以下のようなことが起きていると考える。
- まず、5 と 3 という2つの値をArea製造機(Areaクラス)に突っ込んで、newボタンを押す。
- すると
@length = 5
、@width = 3
という属性がセットされたAreaクラスのオブジェクト(インスタンス)が作られて出てくる。 - 出てきたAreaクラスのオブジェクトに
area
という名前をつける。
areaという名前のオブジェクトのクラス名を調べると、Areaになっていることが確認できる。
area.class # areaのクラス名を調べる #=> Area
Classクラスとは何か?
次に、このAreaクラス自体もオブジェクトだというので、Areaクラスというオブジェクトのクラス名を調べてみる。
Area.class # Areaのクラス名を調べる #=> Class
Areaクラス自体のクラスはClassクラスだということがわかった。
わかりにくいのでクラスを「製造機」と言い換えると、「Area製造機のクラスはClass製造機」となる。
Classクラスは、いろんなクラス、つまりStringクラスやArrayクラスやAreaクラスなどの種類を表しているのと同時に、いろいろなクラス(= 製造機)自体を作り出すClass製造機のことを表している。