Python 基本操作　第3弾：オブジェクト指向とクラス

# #Python 基本操作<オブジェクト指向とクラス>#

##はじめに
自分が不安な部分についてのみ，Pythonの基本操作について復習する．
その第3弾としてオブジェクト指向とクラスについて記述する．

##オブジェクト指向とは？
端的に言えば，データと操作をひとまとめにして扱うもの．
変数と関数をまとめてしまうようなもの．
ひとまとめにしたものを**オブジェクト**という．

オブジェクト指向では，
処理対象をオブジェクト単位で分割し，互いにメッセージをやり取りして処理を進める．
####オブジェクト指向の利点
修正時の影響を最小限にするなど，保守性向上が期待できるところ

##カプセル化
オブジェクト指向には，オブジェクト内部にあるデータには，用意した操作を使ってしかアクセスできないようにする仕組みがあり，それをカプセル化という．以下にそのイメージ図を示す．

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/495792d5-43cf-79ef-a043-97beaf56def4.png)

図1において，処理はオブジェクト外部からの処理を表し，青色の各枠はオブジェクトを表す．オブジェクト内にはデータと操作要素があり，外部から直接にはデータにアクセスできないことが分かる．ただし，操作を踏んでデータにアクセスすることはできる．

##言葉の整理
オブジェクト：データと操作をまとめたもの
クラス：オブジェクト設計図のようなもの
インスタンス：オブジェクトを実体化したもの

以下では，実際のコードで確認を行う．
##コード1

```python:class.py
"""
2020/12/14
@ Yuya Shimizu

クラス
"""
#Userというクラスの定義
class User:
    #コンストラクタ
    def __init__(self, name, password):
        self.name = name
        self.password = password

    #ログインのメソッド
    def login(self, password):
        if self.password == password:
            return True
        else:
            return False

    #successのメソッド
    def success(self):
        print('User: ' + self.name + ' --- login successfully !!')
        
    #failureのメソッド
    def failure(self):
        print('User: ' + self.name + ' --- sorry, password is not correct')

#aにインスタンス生成
a = User('Yuya', 'PassWord')

user_input = input('\nplease input your password\n>>')
if a.login(user_input):
    a.success()
else:
    a.failure()
```

``` class~ ```でオブジェクトを設計
``` オブジェクト名() ```でインスタンスを生成
インスタンスに対して操作を指定することで，オブジェクト内にアクセスしている．

##コード2

```python:class.py
"""
2020/12/14
@ Yuya Shimizu

クラス
"""
#Userというクラスの定義
class User:
    #コンストラクタ
    def __init__(self, name, password):
        self.name = name
        self.password = password

    #ログインのメソッド
    def login(self, password):
        if self.password == password:
            return True
        else:
            return False

    #successのメソッド
    def success(self):
        print('User: ' + self.name + ' --- login successfully !!')
        
    #failureのメソッド
    def failure(self):
        print('User: ' + self.name + ' --- sorry, password is not correct')

#aにインスタンス生成
a = User('Yuya', 'PassWord')

user_input = input('\nplease input your password\n>>')
if a.login(user_input):
    a.success()
else:
    a.failure()

# クラスの継承
class GuestUser(User):
    def __init__(self):
        super().__init__('guest', 'guest')

guest = GuestUser()
user_input = input('\nGuest, please input your password\n>>')
if guest.login(user_input):
    guest.success()
else:
    guest.failure()
```
classには継承というものがある．
ある親クラスが定義されており，その親クラスと同じ構造を子クラスに受け継ぐことができる．
継承部分のみを次に示す．

```python
# クラスの継承
class GuestUser(User):
    def __init__(self):
        super().__init__('guest', 'guest')
```

オブジェクト名の後ろに引数として親クラスがあり，さらにクラスの```__init__()```における引数の変更も可能である．```super().__init__()```で実行している．

##Pythonにpublicやprivateのようなアクセス属性はあるのか？
結論から言うとない．
しかし，その代わり```_```や```__```で始まる変数やメソッドは外部から参照しないというルールがあり，アクセスするとエラーが発生する．実際に検証を行う．

##検証

```python:rule_.py
"""
2020/12/14
@ Yuya Shimizu

クラス
アンダーバーのルール
"""
#Userというクラスの定義
class User:
    #コンストラクタ
    def __init__(self, name, password):
        self.name = name
        self.password = password
        self.__password = password
        

#aにインスタンス生成
a = User('Yuya', 'PassWord')

print(a.name)
print(a.password)
print(a.__password)
```

##検証結果
実行結果を次に示す．


```
Yuya
PassWord
Traceback (most recent call last):
  File "D:/Python Skills/基本/オブジェクト指向とクラス/rules__.py", line 25, in <module>
    print(a.__password)
AttributeError: 'User' object has no attribute '__password'
```
実行結果から，```print(a.__password)```の部分のみエラーが出ており，```__```をつけるだけでアクセスできなくなっていることが分かる．

##感想
クラスは何度か使ってきたが，ようやくその仕組みを理解し，納得できた．アンダーバーのルールも知っているようで知らなかったため，ここで理解できてよかった．

##参考文献
Pythonで始めるアルゴリズム入門　伝統的なアルゴリズムで学ぶ定石と計算量
　　　　　　　　　　　　　　　　　　　　　　　　 増井 敏克　著　　翔泳社