CHAPTER 4 · 14 LESSONS · 182 問

同じ形をまとめて作る(クラス)

設計図を書いて、そこから同じ形のデータを何個でも作る。データと振る舞いをひとつにまとめる考え方。

オブジェクトを使えば、1人ぶんのデータは表せるようになった。では10人ぶんだとどうだろう。{ name: ..., age: ... } を10回書くことになる。項目をひとつ増やしたくなったら、10か所すべてに書き足すことになる。

クラスは、この繰り返しをなくす仕組みだよ。「こういう項目を持つものを作る」という設計図を1回書いておいて、そこから実物を何個でも作る。設計図を直せば、そこから作られるものすべてに反映される。

設計図が クラス、そこから作られた実物が インスタンス と呼ばれる。たい焼きの型と、焼き上がったたい焼きの関係だと思えばいい。型は1つ、たい焼きは何個でも。中身のあんこが違っても、形は同じ。

作るときに中身を決めるのが コンストラクタnew Person("ゆい", 15) のように書くと、コンストラクタが呼ばれて、渡した値がそのインスタンスに入る。ここで出てくるのが this で、「いま作られようとしている、この実物自身」を指す。this.name = name は「この実物の name という項目に、受け取った値を入れる」という意味だよ。this は最初とっつきにくいけれど、「自分自身」と読みかえれば分かりやすくなる。

次が メソッド。クラスの中に書いた関数で、そのインスタンスのデータを使って何かをする。ここがクラスの本当の価値だ。データと、そのデータを扱う処理が、ひとつの場所にまとまる。人の情報と、人に対してやりたいことが離れて散らばらない。

章の後半は 継承。すでにあるクラスをもとにして、少しだけ違うクラスを作る仕組みだよ。「動物」クラスがあって、そこから「犬」クラスを作る。共通の部分は書き直さず、違うところだけを足す。extends で受けつぎ、super で元のクラスの処理を呼び出す。同じ名前のメソッドを書けば、元の動きを上書きできる。

クラスは、ここまでの章で覚えたものの集大成でもある。変数・関数・オブジェクトが分かっていないと組み立てられないし、逆にそれらが分かっていれば、クラスは「まとめ方のルール」を足しただけのものだと分かる。

継承には使いすぎの落とし穴もある。「AはBの一種だ」と自然に言えるときだけ使うのが安全だよ。「犬は動物の一種だ」は成り立つけれど、「たまたま似た処理があるから継承しておこう」でつなぐと、片方を直したときにもう片方が壊れるようになる。継承は共通化の道具ではなく、関係を表す道具だと考えておこう。

この章でつまずきやすいのは、やはり this だよ。同じ this でも、どこに書いたかで指すものが変わる。コンストラクタの中では「いま作られている実物」、メソッドの中では「そのメソッドを呼び出した実物」を指す。混乱したら「誰の話をしているのか」を声に出して確かめるといい。

もうひとつ、クラスとインスタンスを混同しないことも大事だよ。クラスは型であって、そこには具体的な値は入っていない。値が入るのは、new で作った実物のほうだ。この2つを取りちがえると、「なぜ値が取れないのか」で長く悩むことになる。

この章を進めるときは、まず紙かメモに設計図を書いてみるといい。「このクラスはどんな項目を持つか」「どんなことができるか」を先に言葉にしてから、コードに落とす。いきなり書きはじめると、途中で項目が足りないことに気づいて何度も書き直すことになるよ。

なお、実際の開発ではクラスを使わない書き方も多い。それでも他人のコードには必ず出てくるし、データと処理をひとまとめにするという発想自体は、クラスを使わない設計でも生きてくる。読めるようにしておくことには十分意味があるよ。

この章のレッスン

設計図と実物

  1. 50オブジェクトをもう一度名前と値の組で情報を持つ形を思い出そう。新しい文法は出てこない、感覚を戻すためのレッスンだよ。 問題へ
  2. 51クラスは同じ形の設計図同じ形のオブジェクトを量産するための設計図、クラスの考え方と書き方を知ろう。 問題へ
  3. 52設計図から実物を作るnew で設計図から実体を作り出し、プロパティを持たせて読み出そう。この実体をインスタンスと呼ぶよ。 問題へ

作るときの初期化

  1. 53作るときに自動で走る処理クラスの中に書いたコンストラクタが、new のたびに自動で動くことを確かめよう。 問題へ
  2. 54this で中身を持たせるコンストラクタの中で this.名前 = 値 と書いて、生成と同時にプロパティを用意しよう。 問題へ
  3. 55作るときに値を渡すコンストラクタに引数を受け取らせて、実体ごとに違う中身を持たせよう。 問題へ

振る舞いを持たせる

  1. 56クラスに動きを持たせるクラスの中に書いた関数、メソッドを、インスタンスから呼び出そう。 問題へ
  2. 57メソッドから自分の中身を見るメソッドの中で this.プロパティ と書いて、呼び出された実体自身が持つ値を使おう。 問題へ
  3. 58メソッドから別のメソッドを呼ぶメソッドの中で this.別のメソッド() と書いて、処理を組み合わせよう。 問題へ

受けついで作りかえる

  1. 59あるクラスをもとに作るextends を使って、すでにあるクラスの中身を引き継いだ新しいクラスを作ろう。 問題へ
  2. 60受け継いだ機能を使う親クラスに書いたメソッドを、子クラスのインスタンスから呼び出そう。 問題へ
  3. 61子だけの機能を足す子クラスに独自のメソッドを書いて、親には無い動きを持たせよう。 問題へ
  4. 62受け継いだ動きを差し替える親と同じ名前のメソッドを子で書き直して、その子だけ動きを変えよう。 問題へ
  5. 63親の処理を呼んでから足す子でコンストラクタを書き直すときの super() と、親のメソッドを呼ぶ super.メソッド() を使おう。 問題へ

つぎは「ファイルを分ける・借りてくる」。長くなったコードを役割ごとにファイルへ分け、他の人が書いた部品を取り込んで使う。