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

Posted on 2019/03/24 in programming , Updated on: 2019/03/30

はじめに

オブジェクト指向プログラミングは、モノを組み立てていくように構造を作っていく記法である。 例えば、「人間」というオブジェクトを構成する際に、中身に名前や年齢、住所といった情報を持ち、 話す、歩く、考えるなどの行動をとれるというように、内容を追加していくイメージ。

class Human():

上記では、Human()クラスとして、「人間」オブジェクト(=インスタンス)を作成している。 この Human() に、名前や年齢などの属性を持たせ、 また後から追加・編集するようにすることで、オブジェクト数や属性量が膨大になっても簡単に再利用することが可能となる。

Class の定義

クラスの定義は、class キーワードから初めて、任意のクラス名を追加する。この際、Python ではクラス名は、 キャメルケース表記で記す。全ての class はインスタンスを作成し、全てのインスタンスはアトリビュート(属性)を持つ。

下記の Human() クラスの場合、それぞれの人間は特定の名前と年齢を持つことを示している。

# クラスの定義
class Human():

    # インスタンスアトリビュートの定義
    def __init__(self, name, age):
        self.name = name
        self.age = age

# インスタンスを作成
human1 = Human('Taro', 25)

ここで、__init__()コンストラクタと呼ばれ、クラスの初期化をするために必要なメソッドである。 これがあることで、この Human() を利用するたびに新しくインスタンスが作成され、それぞれインスタンスアトリビュートが与えられる。 つまりクラスを再利用していくつもの異なるインスタンスを簡単に作成することができる。

human2 = Human('Hanako', 20)
human3 = Human('Koji', 19)
human4 = Human('Misaki', 23)

また、アトリビュート( self.name や self.age ) は、それぞれのインスタンスで固有のものを指定するが、 この Human() クラスによって生成されるインスタンスに同じ属性を与えることもできる。

下記例で定義した Human() は、生成される各インスタンスは個別の名前と年齢を持つが、 全てのインスタンスは、学名=ホモ・サピエンスという共通のアトリビュートを持つ。

class Human():

    # クラスアトリビュートの定義
    Scientific_name = 'Homo sapiens'

    def __init__(self, name, age):
        self.name = name
        self.age = age

作成したクラスを用いて、インスタンスを作成、操作をしてみる。human1human2というインスタンスを作成し、 それぞれのインスタンスアトリビュート(名前、年齢)、およびクラスアトリビュート(学名)を呼び出す。

human1 = Human('Taro', 25)
human2 = Human('Hanako', 20)

print(human1.name)
# 'Taro'

print(human2.age)
# 20

print(human1.Scientific_name + ' and ' + human2.Scientific_name)
# Homo sapiens and Homo sapiens

インスタンスメソッド

インスタンスメソッドは、クラス内で定義される関数で、インスタンスの内容を取得するために使用される。これらは、 クラス内のインスタンスアトリビュート(Human()では名前や年齢)を利用して操作を実行することも可能。 また、コンストラクタと同様に、最初の引数は必ずselfとする。

class Human():

    # クラスアトリビュートの定義
    Scientific_name = 'Homo sapiens'

    def __init__(self, name, age):
        self.name = name
        self.age = age

    # インスタンスメソッドの定義
    def description(self):
        return "{} is {}.".format(self.name, self.age)

    # 引数を追加したインスタンスメソッドの定義
    def bloodtype(self, type):
        return "{}'s blood type is {}.".format(self.name, type)

# インスタンスを作成
human3 = Human('Koji', 19)

# インスタンスメソッドを呼び出す
print(human3.description())
# Koji is 19.
print(human3. bloodtype('AB'))
# Koji's blood type is AB.

クラスの継承

あるクラスが別のクラスのアトリビュートとメソッドを引き継ぐプロセスをクラスの継承という。 新しく形成されたクラスは子クラス、元のクラスを親クラスと呼ぶ。

子クラスは親クラスの機能をオーバーライド(上書き)や拡張することが可能である。 つまり子クラスは親クラスの全てのアトリビュートとメソッドを継承するが、異なる動作を追加することもできる。 次の例では、親クラスHuman()を継承するStudent()OfficeWorker()の2つの子クラスを定義している。

class Human():

    Scientific_name = 'Homo sapiens'

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def description(self):
        return "{} is {}.".format(self.name, self.age)

    def bloodtype(self, type):
        return "{}'s blood type is {}.".format(self.name, type)    

# 子クラス1 (Human()を継承)
class Student(Human):
    def go_to(self, place):
        return "{} goes to {} everyday.".format(self.name, place)

# 子クラス2 (Human()を継承)
class OfficeWorker(Human):
    def go_to(self, place):
        return "{} goes to {} everyday.".format(self.name, place)


Misaki = OfficeWorker('Misaki', 24)
print(Misaki.description())
# Misaki is 24.

print(Misaki.go_to('office'))
    # Misaki goes to office everyday.

クラスのオーバーライド

子クラスは、親クラスのアトリビュートやメソッドをオーバーライド(上書き)することができる。

class Human():
    Scientific_name = 'Homo sapiens'

class ModernPeople(Human):
    pass

class OldPeople(Human):
    Scientific_name = 'Archaic humans'

Kenta = ModernPeople()
print(Kenta.Scientific_name)
# Homo sapiens

Ryoko = OldPeople()
print(Ryoko.Scientific_name)
# Archaic humans