運動会のプログラムとオブジェクト指向

[他の記事にコメントを書いた](http://qiita.com/masaaki-tsuyoshi/items/61571efb34862476310f#comment-f7810d6229651960e986)のですが、せっかくなので加筆・修正して記事にしておきます。

# 運動会のプログラム

私が生まれて初めて「プログラム」という言葉を知ったのは、小学校の運動会のときに配られた紙の「プログラム」でした。
何がどの順番で行われるかが書いてある紙です。

```text:運動会のプログラム
1. 開会のあいさつ・・・校長先生
2. 選手宣誓・・・・・・６年３組 山田太郎君
3. ムカデ競争・・・・・４年生
4. 徒競走・・・・・・・２年生
5. 騎馬戦・・・・・・・６年生
：
：
```

**プログラム = program = pro-gram = pro(前に、先に、予め)-gram(書く) = 事前に書いたもの**
(telegram=離れたところに書く=電報、diagram=点を結んで書く=図、grammar=書(文)を知る=文法)
<p/>

テレビのプログラムも事前(放送前)に書かれたもので、いつどこで何がどの順番で放送(実行)されるかが書いてあります。
コンピュータのプログラムも同じで、**必要になったときに実行**できるように**予め書いておくもの**で、何をどの順番で実行するかを書いておきます。

# コンピュータの手続き型プログラム

コンピュータの「**手続き型プログラム**」では、運動会のプログラムに書いてあるように「何をどの順番で実行するのか」に重点を置いて処理手順を書きます。
コンピュータのCPUは命令を順番に処理するのが得意ですから、コンピュータにも適しています。

```text:手続き型プログラム
開会のあいさつをする(校長先生が, みなさんに);
選手宣誓をする(６年３組の山田太郎君が, みなさんに);
ムカデ競争をする(４年生が);
徒競走をする(２年生が);
騎馬戦をする(６年生が);
：
：
```

運動会のプログラムは、見た人が分かりやすいように書かれていて、ひとりの人が全体を把握できる分量です。
手続き型プログラムも、見る人(メンテナンスする人)のことを考えて、ひとりの人が全体の流れと内容を把握できる分量にするといいでしょう。

# 実際の運動会の進行(実行)

実際の運動会の現場には、運動会のプログラムを進行(実行)する**実行委員**がいて**、進行役・進行係**を務めます。
**実行委員**は、**放送係**に場内アナウンスをお願いしたり、**学校代表**である校長先生、**生徒代表**である山田太郎君、**学年担当者**である各学年担当者に**指示(命令)**を出しながら、プログラムを**進行(実行)**していきます。
つまり、**実行委員(進行役・進行係)**という**役目・役割・係**を持った**担当者**が、他の役目・役割・係を持った担当者に行動するよう指示を出していたわけです。
どのように**行動する・対応する・振る舞う**かは**各担当者にまかせ**て、**進行係**は進行具合に応じて**指示を出すことに専念**します。
プログラムに書いてあることは簡単に見えても、実際の進行(実行)には多くの関係者の協力が必要です。

# 実生活の中のオブジェクト指向

運動会だけでなく、学校で部活や行事、会社で仕事やイベントをするときにも、小さな仕事は自分一人で処理して終わらせてしまいますが、**大きな仕事**をするときには**他者の協力が必要**だと思います。そんなとき、**どんな仕事**があって、**誰が**できるか、**誰に**してもらうか、**誰と**してもらうかを考えて**仕事を分担**しますよね。分担をお願いしたらやり方は任せます。割り振られた担当者も一人で仕事するのが大変なら、サブ担当者や関係者に仕事を割り振って**協力・協調**しながら**責任・責務を果たしてくれる**ことでしょう。

# コンピュータのオブジェクト指向プログラム

コンピュータの「**オブジェクト指向プログラム**」も実際の運動会を進行するときのように、「どんな**役目・役割・係**があるのか、**誰が**するのか、**誰と**するのか」に重点を置いて書いたプログラムといえます。
**役目・役割・係**を「**クラス**」または「**インタフェース**」として定義し、仕事に応じた振る舞い方を「**メソッド**」に定義します。個別に行動できる**担当者**を「**インスタンス**」として生成し、仕事依頼者の**口**から発した指示・命令(**メッセージ**)が担当者の**耳**に届いて適切な「**メソッド**」が選ばれ、仕事が振る舞われます。
プログラム内容は手続き型プログラムと同じですが、物事の捉え方、扱い方が人間行動的になっています。

```text:オブジェクト指向プログラム、進行係の振る舞い方
学校代表者 は 校長先生;           // 校長先生の都合が悪くなったら副校長先生が代役
生徒代表者 は 6年3組の山田太郎君;  // 体調不良なら5年2組山田花子さんが代役
学校代表者さん.話してください(みなさんに, 開会の挨拶を);
生徒代表者さん.話してください(みなさんに, 選手宣誓を);
４年生のみなさん.競技してください(ムカデ競争を);
２年生のみなさん.競技してください(徒競走を);
６年生のみなさん.競技してください(騎馬戦を);
：
：
```

「**誰か**」は**人**に限らず、「学校代表者」のような役目・役割・係といった**概念的な名称**で扱うことができます。
漫画やアニメの世界で「あんぱん」や「うんち」に目鼻口耳手足がついて擬人化され、しゃべったり動いたりしますが、そんな風にいろいろな**モノ**に役を演じて(仕事を振る舞って)もらうこともできます。
ただし、**明確**かつ**シンプル**な**責任・責務・係**を与えるようにします。



# オブジェクト指向プログラムの書き方、読み方

オブジェクト指向言語は英語圏で生まれて英文法的に書ける/読めるので、英語圏の人はすんなり理解できて、主語を省略するのに慣れている日本人は理解するのが苦手なのかもしれませんね。

文型|文型(日本語)|意味
---|---|---
S+V     | 主語+動詞                     | **誰か**が、何か**する**
S+V+C   | 主語+動詞+主格補語             | **誰か**が、**なる**、**何か**に
S+V+O   | 主語+動詞+目的語               | **誰か**が、何か**する**、**何か**に/を
S+V+O+O | 主語+動詞+間接目的語+直接目的語 | **誰か**が、何か**する**、**誰か**に、**何か**を
S+V+O+C | 主語+動詞+目的語+目的格補語     | **誰か**が、何か**する**、**誰か**を、**何か**に

C++言語、C#言語、Java言語などでは、主語を省略することができて、そのときは自分(`this`)が仕事することになります。
英語で主語を省略すると命令形になって相手にさせることになるのですが、これらのプログラム言語では英文法とは異なっています。
python言語では主語を省略すると標準ライブラリやグローバル関数呼び出しになるので、英語と同じく他者への命令になります。

私は「こんなことしてくれる奴がいてくれたら便利なんだけどな～」と考えて、まだ存在してない奴をいるものとしてプログラムを書いたあと、その便利な奴になりきって責務を果たすようにクラス定義します。
そのときには「○○君」と擬人化して呼べる名称を付けるようにしています。
もちろん、ちゃんとしたプログラムは要件定義や設計してからプログラムを書きますけどね。

# クラスとインスタンス

クラスとインスタンスの違いも、英単語と合わせて整理しておきましょう。
「猫」と言われて頭の中に何が思い浮かびますか？ 自宅で飼っている実物の猫？
「猫とは何ですか？」と言われて他の人と共通する認識があると思います。それが概念、クラスです。
一匹一匹の実物・実体がインスタンスです。

|英語|日本語|概念か実体か|クラスかインスタンスか|
|---|---|---|---|
| cat | (ペットの)猫(に関すること) | 概念 | クラス |
| cats | (ペットの)猫全般 | 概念 | クラス |
| a cat | (不特定の)とある猫 | 実体 | インスタンス |
| the cat | (特定された)その猫 | 実体 | インスタンス |
| the cats | (特定された)その猫たち | 実体 | インスタンス |

> I like cat.
猫に関することが好き。猫哲学者？猫博士？食べるのが好き？
I like cats.
猫全般が好き。猫好き。
I like the cat.
その猫が好き。他の猫は眼中にない。

「猫」という言葉・概念は、実物を見たあとに作られたものです。

> あそこに4本足の動物(インスタンス)がいる、ここにも4本足の動物(インスタンス)がいる、あっちにも(インスタンス)、こっちにも(インスタンス)。ひとつひとつに名前を付けて呼ぶのは大変だから、特徴が共通のこれらの動物をグループ化、クラス化、抽象化して「猫」と呼ぶことにしよう。
「猫」クラスには「性別」属性があるけれど、「オス」か「メス」かはインスタンスを特定しないと分からない。

コンピュータのプログラムでも、同じ形式のデータを抽出してクラス化します。
> 「氏名、電話番号、住所」のデータが沢山あるので、これを「連絡先」と呼ぶことにしよう。連絡先を複数管理できる「電話帳」も作ろう。
「電話帳」から電話をかけるには、どの電話帳のどの連絡先かを選んでインスタンスを特定すれば電話番号がわかるので、あとは電話をかけられる人にお願いすればいい。