Python#4_関数とクラス

#Python入門その4

###関数、クラス、オブジェクト指向プログラミング
これからプログラミングを本格的に学んでいく際、必ず勉強しなければいけないオブジェクト指向プログラミングの話をします。
そのために、まず初めに関数とクラスについて説明します。

今まで「インスタンス」とか、「カプセル化」とか、「メソッド」とか、言われても？？となりがちな用語もまとめていきます。

##関数
関数はunityでゲームを作るときもよく利用したかと思います。
例えば、`OnCollisionEnter()`などは、unityが用意してくれている関数ですし、なんなら`void Start()`と`void Update`は何も言わずともunityが勝手に呼び出してくれていました。

下のプログラムは、1こ100円のりんごと1こ200円のみかんをいくつか買った時、合計金額を表示するプログラムです。
関数は使っていません。

```php
r = input("apple")
m = input("orange")

total_r = r*100
total_m = m*200

print total_r + total_m 
```

このプログラムを、関数にしてりんごとみかんの個数を入力したら、合計金額を返すプログラムにします。
関数を自分で作ることを***関数を定義する***と言います。
関数を定義するときは以下のように書きます。

```php
def 関数名(第一引数, 第二引数, ...):
    処理1
    処理2
    ...
```

それでは、実際にこのように書いて関数を作ります。

```php
apple = input("apple")#____1
orange = input("orange")

def total_price(r,n):#_____2
    total = r*100 + n*200
    return total

print total_price(apple,orange)#____3
```

それぞれ説明していきます。

まず、1でりんごの個数とみかんの個数を入力しています。これは変わりません。例として、りんごを二個、みかんを四個と入力したとします。

次に、先に3をみてください。3の`total_price()`で関数を呼び出しています。第一引数にりんご、第二引数にみかんを入れているので、ここでは`total_price(2,4)`となります。

最後に2を見てください。rには2が、nには4がそのまま代入されます。
あとは中で処理を行い、`return　total`により、totalの値を戻します。

3のtotal_price(apple,orange)にはtotalの値が返ってくるので、計算した値を出力することができます。

このreturnを***戻り値***,***返り値***と呼びます。

このプログラムをC#でかくと次のようになります。

```php
var apple = int.Parse(Console.ReadLine());
var orange = int.Parse(Console.ReadLine());
int total;

int total_price(int r,int n){
      total = r*100 + n*200;
}

Console.Write(total_price(apple,orange)); 
```

>ex4-1
・ex3-3でも書いた、「オリンピックの年かどうか判断するプログラム」を関数にしてみましょう。
・二つの数字を受け取り、その数字を足した数を返す関数を作ってみましょう。
・底辺の長さと高さを入力して、三角形の面積を計算する関数を作ってみましょう。
・直角三角形があります。90°の角を挟む二つの辺の長さを入力したとき、対応する斜辺の長さを計算する関数を作ってみてください。ヒント：平方根の書き方を調べてみましょう。ピタゴラスの定理。

##クラス
次にクラスについてみていきます。この辺は、専門用語が並び、理解するのが少し苦しくなる場所でもあります。

とは言っても、unityでクラスは死ぬほど扱いました。今までunityでは、クラスにプログラムを書いていたのです。

```php
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class クラス名 : MonoBehaviour
{
 //処理
}
```

こんな感じだったかと思います。
クラスは***設計図***と考えるのがわかりやすいです。
例えば、UnityのPlayerMove.csはプレイヤーを動かす設計図でした。
まずクラスを理解する上で欠かせない5つの単語を覚えてください。

####クラス
クラスはデータを処理するための設計図と覚えましょう。
この中に、どうデータを処理するか書いていきます。

####インスタンス
クラスに従って作られたものを、***インスタンス***と呼びます。
***インスタンスとはクラスを実体化させたもの***です。
クラスがたい焼きの型、とするならば、インスタンスはたい焼きと表現されることが多いです。
unityでは`Instanciate()`という関数がありました。あれは、ボールを出現させるときなどに使ったかと思います。ボールにアタッチしたクラス（c#)に従って、インスタンス化(実体化)させるという意味です。

####オブジェクト 
Pythonでは、「データを抽象的に表したもの」と表現されます。
プログラムでは「データのまとまり」とも言われます。
これではなんのことだかよくわかりません。
クラスとインスタンスをまとめたものだと思ってください。
例えば,unityではゲーム画面にあるCubeを「GameObject」と呼びました。あれはクラスをもとにCubeがインスタンス化（実体化)して、オブジェクトになったものだと考えられます。

####プロパティ
モノ(オブジェクト)が持っているデータを指します。
例えば、車であれば色、人であれば身長などです。

####メソッド
モノ(オブジェクト)が持っている処理を指します。
例えば、車であれば真っ直ぐ進む、人であればジャンプするなどです。


###クラスの書き方
クラスのメリットは、同じ処理のものを大量に作れることです。

例えば、オープンワールドゲームを考えてみましょう。
NPCの車が1000台必要だったとします。車を一台一台作っていたらキリがありません。
そんなとき、クラスを作成し、1000台インスタンス化(実体化)させれば、一瞬でクローンが1000こ作成できます。

実際に書いてみます。

```php
class MyClass:
    x = 10
    def test(self):
        return 'hello'

obj = MyClass()
print obj.x
print obj.test()
```
1~4行目までがclassです。
`obj=MyClass()`がインスタンス化です。
selfについてはあまり気にしなくていいです。これはここに入れるモノなんだなと今は考えてください。

objをインスタンス化したことにより、中のメソッド(処理)が利用できるようになりました。
実際に書いて実行してみてください。
`obj.x` は10と出力され、`obj.test()`はhelloと出力されるはずです。

####__init__　＝　(コンストラクタ)
classを作成する際に欠かせないものが、***__init__メソッド***です。***コンストラクタ***と呼ばれています。
簡単にいうと初期設定を行うメソッドです。

```php
class クラス名:
    def __init__(self,  他の引数):
        初期設定
```

pythonをかくときはこれがデフォルトの決まり文句だと思ってください。このようにしてクラスを初期設定し、使います。
実際に使い方を見てみましょう。

```php
class Human:
    def __init__(self,name):
        self.myname = name
    def hello(self):
        print "myname is " + self.myname

John = Human('John')
John.hello()

Bob = Human('Bob')
Bob.hello()
```

クラスHumannを作りました。
initにより初期設定を行なっています。
nameに引数が入り、それぞれJohn,Bobの名前が入ります。
これでJohnとBobをインスタンス化することができました。
あとは、John.hello()などでメソッドを呼び出すことができます。
付け足してみましょう

```php
class Human:
    def __init__(self,name):
        self.myname = name
    def hello(self):
        print "myname is " + self.myname
    def run(self):#追加
        print self.myname + " is running"#追加

John = Human('John')
John.hello()
John.run()#追加

Bob = Human('Bob')
Bob.hello()
```

これでHumanでインスタンス化された人はみんなrunというメソッドが使えるようになりました。

>ex4-2
・上のプログラムに書き足します。年齢を追加し、年齢を答えるメソッドを作ってみましょう。ヒント：initコンストラクタ、`John=Human('John')を書き換えます。

####オブジェクト指向の三原則
１：継承
同じようなプログラムを一箇所にまとめてコードを再利用しやすくする

２：カプセル化
オブジェクトが持つデータや処理の中で、他のプログラムからいじられたくないものを隠すこと。

３：ポリモーフィズム
継承したコードの中で、コードを一部変更して利用するための仕組み

この辺りは僕がここでかくよりも自分で調べた方が早いと思うので、実際に調べてみましょう。

>ex4-3
かんたんなじゃんけんゲームを作ってみましょう。
・自分は'gu','choki','pa'のいずれかを入力します。
・同じようにランダムでじゃんけんをするNPCをつくります。
・どっちがかったか表示するようにしましょう。
・勝敗が付くまでずっと勝負が続くようにしましょう。
・'fin'と入力したら強制終了できるようにしましょう
ヒント：
１`import random`で乱数が使えます。
２`変数=random.randint(〇,×)`で〇から×までのランダムな数字が変数に入ります。