初学者のためのPython講座　オブジェクト指向編2　クラスとインスタンス

# クラスとインスタンス

上から順に処理を実行していくプログラムのことを「手続き型」プログラミングといいます。これに対して、オブジェクト指向プログラミングではオブジェクトを生成し、オブジェクトを組み合わせてプログラムを構築します。

このオブジェクトの生成に必要なものが**クラス**です。クラスとは、オブジェクトの**特性を記述したもの**で、簡単に言うとオブジェクトの仕様が書かれた**設計図**です。そして、クラスから生成されたオブジェクトを**インスタンス**といいます。

**クッキーの型をクラス**、**クッキーをインスタンス**に例えると、クッキー型（クラス）を使うことによって大量の同じ形のクッキー（インスタンス）を作ることができます。また、材料（データ）を変えることで種類の異なるクッキー（インスタンス）ができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/270994/ea801974-4347-e665-c207-655612665df0.png)

**クラス**はあくまで**型**であって中身がなく、インスタンスの特性を記したものです。具体的なデータを与えることで**実体**として**インスタンス**が生成されます。

また、上図の例ではクッキー型という実体がありますが、**様々な種類のクッキーの総称**として、まとめて「クッキー」と呼ぶことができます。総称としてのクッキーに実体はなく、クッキーの特徴だけを集めたものです。これを、オブジェクト指向では**抽象化**といいます。**クラス**もまた実体がなく特徴だけを集めた**抽象**であり、**具体**化したものが**インスタンス**と捉えることができます。


## クッキーを表すクラスを設計してみよう
クラスを設計することを**クラス定義**といいます。そして、クラス定義には**class文**を使用します。

```【書式】class文によるクラス定義.py
class クラス名:
    クラスの内容
```

クラス定義の書式は、関数を定義する書式に似ています。クラスの内容はインデントしたブロックに記述します。また、**クラス名は慣習的に大文字で始めます**。大文字で始めることで関数とクラスの判別をしやすくするためです。

では実際にクッキーのクラスを定義してみましょう。


```cookie_class.py
class Cookie:
    pass
```

これでクッキーのクラスが定義できました。クラスの内容は、ここでは何も実行しない`pass`を記述しています。

## クッキーのクラスからインスタンスを生成する
クラス定義によってクッキー型はできましたが、まだ実体がありません。ここからクッキー型（クラス）を元に、クッキー（インスタンス）を生成する必要があります。

クラスからインスタンスを生成するには、以下の書式で記述します。

```【書式】クラスからインスタンスを生成.py
インスタンス名 = クラス名()
```

インスタンスの生成も、関数を呼び出すときと同じように、クラス名に括弧()を付けて変数に代入します。

では先ほどの`Cookie`クラスからクッキー（インスタンス）を作りましょう。


```cookie_instance.py
class Cookie:
    pass

cookie1 = Cookie()
```

`Cookie`クラスから`cookie1`というインスタンスが生成できました。
クラスの内容には`pass`しか記述していないため、`cookie1`インスタンスには何のデータもありません。これだけでは味気ないので、次はクッキーにデータを与えましょう。

## クラス変数とインスタンス変数
**データ（属性）**と**メソッド（操作）**を一つのまとまりにしたものがオブジェクトです。クラスにデータを設定することで、共通のデータを持つインスタンスが生成されます。このような共通データを**クラス変数**といいます。一方、それぞれのインスタンスが持つデータを**インスタンス変数**といいます。
クラスをクッキー型とするなら、クラス変数が共通のクッキーレシピ、インスタンス変数は実際のクッキー生地やトッピングに例えられます。

※ クラス変数やインスタンス変数をクラス（インスタンス）の**アトリビュート**や**属性**ともいいますが、ここでは**クラス（インスタンス）変数**で統一します。


以下の書式でクラス変数を設定します。

```【書式】クラスにクラス変数を設定する.py
class クラス名:
    クラス変数名 = 値
```

また、クラス変数、インスタンス変数、それぞれの値を呼び出すには以下の書式で記述します。

```【書式】クラス・インスタンス変数の値を呼び出す.py
クラス名.クラス変数名
インスタンス名.インスタンス変数名
```

それでは、先ほどのクッキー型にレシピを与え、レシピ通りのクッキーができたか確認してみましょう。

ここでは、`Cookie`クラスにクラス変数`taste`と`name`のデータを設定し、クラス変数を呼び出して表示。その次に、`cookie1`インスタンスを生成し、`cookie1`のインスタンス変数を呼び出して表示します。

```cookie_class2.py
class Cookie:
    # クラス変数を設定する
    taste = "プレーン"
    name = "クッキー"

# クラス変数を呼び出し表示する
print(Cookie.taste, Cookie.name)
# インスタンスを生成する
cookie1 = Cookie()
# インスタンス変数を呼び出し表示する
print(cookie1.taste, cookie1.name)
```

実行してみましょう。

```
プレーン クッキー
プレーン クッキー
```

クッキー型に与えたレシピからプレーン味のクッキーができました。

クッキーインスタンスは、クラスで設定された初期データ（クラス変数）が与えられ、プレーン味のクッキーとして作成されます。結果として表示されている内容はどちらも``プレーンクッキー``ですが、このとき呼び出している変数は、1行目が**クラス変数（レシピ）**、2行目は**インスタンス変数（クッキー自体の情報）**という違いがあります。

## インスタンス変数を追加・更新する
では、クッキーインスタンスの`taste`データを更新して、違う種類のクッキーも作成しましょう。さらに、インスタンス変数を追加して、クッキーの値段をつけます。インスタンス変数を追加・更新するには、値を呼び出すときと同じ書式を使います。

```【書式】インスタンス変数の値を追加・更新する.py
インスタンス名.インスタンス変数名 = 値
```

それでは、先ほどのクッキーインスタンスのデータを追加・更新し、呼び出してみましょう。

```cookie_class3.py
class Cookie:
    # クラス変数を設定する
    taste = "プレーン"
    name = "クッキー"

# インスタンスを生成する
cookie1 = Cookie()
cookie2 = Cookie()

# インスタンス変数の値を更新する
cookie2.taste = "チョコ"

# インスタンス変数を追加する
cookie1.price = 100
cookie2.price = 200

# インスタンス変数を呼び出し表示する
print(cookie1.taste, cookie1.name, cookie1.price, "円")
print(cookie2.taste, cookie2.name, cookie2.price, "円")

```

実行してみましょう。

```
プレーン クッキー 100円
チョコ クッキー 200円
```

`cookie2`の`taste`データを更新して、プレーン味からチョコ味に変更ができました。また、新たに値段のデータを追加することができました。
このように、インスタンス変数はクラス定義の外から追加・更新ができます。クラス定義に存在しないデータを、インスタンスが独自に持つことができる点は、他のプログラミング言語にはあまりない特徴です。


## クラス変数を追加・更新する
実は、インスタンス変数と同様に、クラス変数もクラス定義の外から追加・更新することが可能です。

```【書式】クラス変数の値を追加・更新する.py
クラス名.クラス変数名 = 値
```

それでは、先ほどのクッキークラスのデータを更新し、呼び出してみましょう。

```cookie_class4.py
class Cookie:
    # クラス変数を設定する
    taste = "プレーン"
    name = "クッキー"

# インスタンスを生成する
cookie1 = Cookie()
cookie2 = Cookie()

# インスタンス変数の値を更新する
cookie2.taste = "チョコ"

# クラス変数の値を更新する
Cookie.name = "せんべい"

# インスタンス変数を呼び出し表示する
print(cookie1.taste, cookie1.name)
print(cookie2.taste, cookie2.name)
```

実行してみましょう。

```
プレーン せんべい
チョコ せんべい
```

クラス変数の`name`データを更新して、クッキーがせんべいになりました。


ただし、このようにクラス定義の外部でクラス変数を変更されるプログラムは**推奨されません**。
オブジェクト指向において、クラスはオブジェクトの設計図であり、型でもあります。クッキー型が途中でせんべい型に代わることは、設計者が望まない変更と言えるでしょう。
また、同様にチョコ味への変更、つまりインスタンス変数の値の更新も推奨されません。あらかじめ与えられたクラス変数を更新することで、意図せずクラス変数を隠蔽してしまうためです。**クラス変数はすべてのインスタンスで共通の変数**、**インスタンス変数はそのインスタンス固有の変数**であるべきなのです。

***
[初学者のためのPython講座　オブジェクト指向編1　オブジェクト指向とは](https://qiita.com/kotakahe/items/9de3b515f8faf01510f0)
[初学者のためのPython講座　オブジェクト指向編2　クラスとインスタンス](https://qiita.com/kotakahe/items/3de8d471ea871b0a7024)
[初学者のためのPython講座　オブジェクト指向編3　メソッド](https://qiita.com/kotakahe/items/3360898ff84c2c141a1b)
[初学者のためのPython講座　オブジェクト指向編4　初期化メソッド](https://qiita.com/kotakahe/items/db3e9fa9d547bb6e9014)

随時追加予定