カニゲーム攻略日記ブログ

beatmaniaIIDXやハースストーンなどのゲーム攻略日記。主にまったり勢。2016年にIIDX皆伝になった

オブジェクト指向がなんだか分からんのでメモ

reference:

オブジェクト指向について一席 – 10bace LOG

contents

オブジェクト指向言語

オブジェクト指向言語とは、プログラミング(コンピュータに命令を出すこと)のやり方の一つで、物や人、あるいは考え方などを"オブジェクト"という箱に入れて考える方法のことを言います。

例えば、小学校のクラスを考えてみましょう。

  • 「生徒」は「名前」や「年齢」、「テストの点数」などの情報(これをプロパティと言います)を持っていますし、「勉強する」「遊ぶ」といった行動(これをメソッドと言います)をとります。これら全てを一つの「オブジェクト」として考えることができます。

  • 「先生」もまた、「名前」や「教える科目」といった情報と、「教える」「注意する」といった行動を持つオブジェクトとして考えることができます。

  • そして、「クラス」もまた、複数の「生徒」や「先生」などを含む大きなオブジェクトとして考えることができます。

オブジェクト指向言語では、これらのオブジェクトを作ったり、情報を設定したり、行動をさせたりすることで、プログラムを組んでいきます。これがオブジェクト指向プログラミングです。

なので、あなたがもし、「生徒」や「先生」、「クラス」といったオブジェクトを作り、それらを使って何かを表現したり動かしたりするプログラムを作ったことがあるなら、あなたは既にオブジェクト指向プログラミングをしていることになります。

なぜオブジェクト指向

あなたがお部屋を片付けるとき、物をどこに片付けるか考えると思います。おもちゃはおもちゃ箱に、本は本棚に、といった具体的な場所に物を置いていくと、探し物をするときにも簡単ですよね。なぜなら、物の種類ごとに決まった場所に置いてあるからです。

一方、物が散らかっていると、探し物をするときにどこに何があるのかわからなくなってしまいますよね。

これと同じように、プログラミングでも色々な「物」(データや処理)があります。そして、それらを整理するために、オブジェクト指向言語が生まれました。

オブジェクト指向言語では、それぞれの「物」を「オブジェクト」という特定の箱に入れて管理します。それぞれのオブジェクトは自分の「名前」(属性)と「動き」(メソッド)を持っています。

例えば、「犬」というオブジェクトなら、「名前」は「ポチ」、「動き」は「走る」や「吠える」などです。これらの情報を一つの「箱」(オブジェクト)にまとめておくことで、どこに何があるのかがわかりやすくなり、コード全体が整理されます。

これにより、プログラミングが簡単になり、誰が見ても理解しやすくなります。また、新しい機能を追加するときも、新しい箱(オブジェクト)を作ればよいので、より簡単になります。

ただし、すべてを箱に入れてしまうと、箱を開けて中身を取り出す手間がかかるので、パソコンの動きが遅くなることもあります。これが「トレードオフ」(得るものと失うものがある状況)です。でも、このトレードオフをうまく利用して、より良いプログラムを作るのがプログラマーの仕事なんですよ。

オブジェクト指向プログラミング

あなたが楽しみにしているテレビのアニメシリーズを考えてみましょう。そのアニメにはたくさんのキャラクターが登場しますよね。それぞれのキャラクターは自分だけの特徴や性格、スキルがあり、それぞれのエピソードで違う冒険をしていきます。

しかし、もしある日、突然新しいキャラクターが登場し、そのキャラクターだけが持つ特別な能力やルールがあったら、それが理解できますか?それとも、混乱しますか?

それと同じように、プログラミングの世界でも「オブジェクト指向プログラミング」という考え方があります。それは「すべてのものをオブジェクトとして見る」というシンプルな考え方から始まります。

ただし、プログラムを作るためには、ただオブジェクトを作るだけではなく、オブジェクト同士がどのように「会話」(メッセージング)するかということも重要です。それができなければ、オブジェクト指向プログラミングとは言えないのです。

しかし、時には新しいキャラクターのように、オブジェクト指向プログラミングの話をしているつもりでも、本当に大切な「オブジェクト」と「メッセージング」の話からはずれて、余計なこと(オプション)を説明することがあります。

これは、アニメの新キャラクターが特別なルールで混乱を招くように、オブジェクト指向プログラミングの本質からはずれて、理解を難しくしてしまうことがあるのです。

だから、もしあなたが「オブジェクト指向プログラミング」について学びたいと思ったら、まずは「オブジェクト」と「メッセージング」について学んでください。それがオブジェクト指向プログラミングの本質です。

そして、余計なオプションの話が出てきたら、それはその話の「新キャラクター」で、その時は必要に応じて学べばいいのです。でも、それが「オブジェクト指向プログラミング」の全てではないことを覚えておいてください。

オブジェクト

オブジェクトっていうのは、まるでおもちゃのロボットみたいなものだよ。それぞれのロボットは自分自身の色や大きさといった特徴(これを「状態」というんだ)を持っているし、他のロボットとお話(これを「メッセージ」というんだ)することもできるんだよ。

たとえば、赤いロボットが青いロボットに「おい、お前、青いな!」って言うと、青いロボットは「そうだよ、僕は青いんだ!」って答えるんだ。これがロボット同士の「通信」だね。

だけどね、このロボットたちはお互いに話しかけあわなければ存在を認識できないんだ。だから、もし赤いロボットが一方的に青いロボットに話しかけても、青いロボットから何も返事がなければ、赤いロボットにとって青いロボットは「存在しない」みたいなものなんだよ。

また、これらのロボットたちは「おもちゃのロボット」という大きなグループに属しているけど、それぞれが個別に動くことができるんだ。だから、ひとつひとつのロボットが「オブジェクト」なんだよ。たとえば、お父さんロボットとお母さんロボットと赤ちゃんロボットがいたとしても、それぞれが独立したオブジェクトだよ。だけど、お父さんロボットがお母さんロボットと赤ちゃんロボットに「おい、家族だぞ!」と言うと、それぞれが家族としての「関連」を持つことになるんだ。

なので、オブジェクトっていうのは、独立した存在で、自分の特徴を持っていて、他のオブジェクトと通信できる、おもちゃのロボットみたいなものだと思っておけばいいよ。

衰退しない

君がお部屋で一人でいろんなおもちゃで遊んでいるとき、各おもちゃがどう動くか、どう相互作用するかを考えるんだよね。たとえば、ロボットが車に乗ったり、お人形がお茶会を開いたりするんだ。これがまるで各おもちゃがそれぞれ自分の独立した「オブジェクト」として行動しているように見えるよね。

でもね、たとえば君が新しくスーパーマーケットのおもちゃセットを手に入れたとしよう。その新しいおもちゃセットを使うと、君の遊び方が変わるかもしれないよね。でもそれは君がおもちゃを使う基本的な方法、つまり「おもちゃで遊ぶ」という考え方が衰退したわけではないよ。単に新しいおもちゃを使って遊んでいるだけなんだ。

これが「マイクロサービス」の話に当てはまるんだよ。マイクロサービスという新しい考え方を使うと、プログラミングの方法が少し変わるかもしれないけど、それは「オブジェクト指向プログラミング」という基本的な考え方が衰退したわけではないんだ。

だからね、「オブジェクト指向プログラミングは衰退する」というのは、ちょっとおかしい考え方なんだ。「おもちゃで遊ぶ」という基本的な考え方が変わるわけじゃないように、「オブジェクト指向プログラミング」という基本的な考え方も変わらないんだ。

ただ、君が特定のおもちゃや遊び方を好きでなくなることはあるかもしれないよ。それはそれでまた違った話なんだけどね。

クラス

ええと、これをお菓子作りの例え話で説明してみるね。

お菓子を作るとき、いろんな材料を使うよね。でも、たくさんの材料を使うと、作るのも難しくなるし、何が何だかわからなくなってしまうこともあるよね。

それがプログラミングでも同じで、クラスという材料をたくさん使うと、プログラムが難しくなってしまうんだ。だから、なるべくシンプルに保つために、本当に必要なときだけクラスを作るようにするんだ。

でも、メッセージという特別な材料を使うことは大丈夫。それはたとえば、お菓子のレシピを書くようなもので、それを使うことで、他の人もどうやってそのお菓子を作ったのかがわかるようになるんだ。だから、メッセージとして使うためのクラスを作るのはOK。

ただし、そのメッセージの中身を変えてしまうと、他の人が混乱してしまうから、一度作ったらそのままにしておくべきだよ。

それから、お菓子を作るときには、たくさんの手順があるけど、それぞれを独立したステップとして考えるのも大切だよ。それが手続き的な考え方で、たとえば「卵を割る」「バターを溶かす」などの手順を1つ1つ分けて考えるんだ。

このように、クラスという材料を上手に使いながら、シンプルさを保ち、適切な手順でお菓子を作るのが、良いプログラムを作る方法なんだよ。

抽象化

うーん、これはね、公園で遊ぶおもちゃ箱の話で考えてみよう。

公園にはたくさんのおもちゃがあって、それぞれが自分の役割を持っているよね。滑り台は滑るためのもの、ブランコは揺れるためのもの。でも、それぞれがどう動くか、どう作られているかまで知らなくても遊べるよね。それがカプセル化だよ。それぞれのおもちゃが自分の内部の詳細を隠して、必要な機能だけを提供しているんだ。

抽象化も同じで、おもちゃ全体を「遊ぶもの」としてまとめて考えることができるんだ。それぞれのおもちゃがどんな形をしていて、どんな機能を持っているかは、全体としての「遊ぶもの」という考え方には影響しないよね。それが抽象化の力だよ。

でも、たまに遊び方を変えたくなることもあるよね。滑り台を逆に登るとか、ブランコを前後ではなく左右に揺らすとか。そういうときには、おもちゃの具体的な形や機能を考えなければならない。それが具象化の部分だよ。

このように、おもちゃ箱の中のおもちゃをどう扱うか、どう考えるかが、ソフトウェアの設計に似ているんだ。どんなおもちゃがあって、それぞれがどう動くかを理解しながら、全体としての「遊ぶもの」という視点を持つ。それが良いプログラムを作る方法なんだよ。

インターフェイス

うーん、それはさ、おもちゃ箱の中のおもちゃで考えてみようね。

おもちゃ箱には、色んなおもちゃがあるよね。たとえば、ブロックとレゴは形が似ていて、どちらも積み重ねる遊びができるから、同じようなおもちゃだと思うかもしれない。

でも、ブロックは単純な形をしていて、積み重ねる以外の遊び方は難しい。一方、レゴは細かいパーツがたくさんあって、自分の好きな形に作り変えることができるよね。

だから、両方とも積み重ねるおもちゃだからといって、同じように扱ってしまうと、レゴの面白さを生かせないよね。

それと同じで、プログラミングでも、似ているように見える部分を同じように扱うと、その部分の本当の特性や役割を理解できないことがあるんだ。

だから、プログラムの一部を作るときは、その部分が何をするものなのか、どういう特性を持っているのかをよく考えてみてね。それが違うものなら、同じように扱うのではなく、違うものとして扱うべきだよ。

それができると、プログラム全体が上手く動くようになるし、何か問題が起きたときにも、その部分が何をしているのかを理解していれば、問題の原因を見つけやすくなるんだよ。