プログラミング経験者は必ず耳にしたことであろう「オブジェクト指向」。それに付随して「クラス」というワードもよく見かけると思います。
「クラス」はオブジェクト指向の中で中核の概念です。Pythonもオブジェクト指向をサポートする言語であり、クラスを実装することができます。
今回はクラスの基本的な意味とPythonでの実装、挙動について見ていこうと思います。
クラスとは
クラスはざっくりというとオブジェクトの設計図です。クラスという設計図から、実体としてのオブジェクト(インスタンス)を作成します。クラスにはオブジェクトに共通する属性(変数、データ)や処理(関数、メソッド)を定義します。
クラスなしにオブジェクトを作成しようとすると、オブジェクトを作るごとに毎度全ての属性や処理を定義する必要が出てきます。クラスはオブジェクトの共通部分を予め定義しておくことでオブジェクト作成時に使いまわせ、コードの可読性や保守性に向上に一役買っています。
Pythonのクラス
ここからは、Pythonで実際にクラスを定義し、クラスからオブジェクトを作成してみます。
定義の基本
Pythonではclassによってクラスを定義します。
class Car():
pass
中身をpassとしていますが、これは特に処理がないことを意味します。
インスタンスの作成
インスタンスの作成は、クラスを呼び出すだけです。
class Car():
pass
if __name__ == "__main__":
car = Car()
carはCarタイプのオブジェクトになります。現状carは属性や処理を保持していない空のオブジェクトです。
コンストラクタ
多くの場合、クラスにはコンストラクタを定義します。コンストラクタはインスタンスを生成した際に実行する処理を定義します。
ここにはインスタンスの属性などを定義する場合が多いです。もちろん、関数など処理を実行することもできます。
コンストラクタはdef __init__で定義します。__init__はPythonにおける特殊メソッドで、コンストラクタの定義は必ず__init__にて定義します。
class Car():
#コンストラクタ
def __init__(self,name):
self.name = name
self.drive_system = "FF"
self.power = 1
if __name__ == "__main__":
car = Car("N Box")
print(car.name)
print("駆動方式: "+car.drive_system)
>>N Box
駆動方式: FF
コンストラクタの第1引数や変数定義にselfが入っていますが、これはそのインスタンス自身を指しているものです。このselfは省略できないため注意してください。クラス定義の際の定型構文として理解しておけばOKです。
メソッドの定義
続いてクラスにメソッドを定義してみます。基本はクラス内で通常のPythonの関数を定義します。
class Car():
#コンストラクタ
def __init__(self,name):
self.name = name
self.drive_system = "FF"
self.power = 1
#メソッド
def run(self):
return 100 * self.power
Carクラスにメソッドrun()が定義されました。ここの引数にもselfが必要です。
これを実行してみます。
if __name__ == "__main__":
car = Car("N Box")
print("時間当たりの走行距離: "+str(car.run()))
>> 時間当たりの走行距離: 100
継承
既存のクラスの定義構造を受け継いだクラスを設計することもできます。このことを継承と言います。このとき、受け継がれる側(既存)のクラスを「親クラス」、親クラスの定義を引き継いで作るクラスを「子クラス」と呼びます。
言葉だけではイメージしづらいので、実際にコードを書いてみます。先ほどのCarクラスを親クラスとして、子クラスであるSuperCarクラスを定義してみます。
#親クラス
class Car():
#コンストラクタ
def __init__(self,name):
self.name = name
self.drive_system = "FF"
self.power = 1
def run(self):
return 100 * self.power
#子クラス
class SuperCar(Car):
#コンストラクタ
def __init__(self,name):
#親クラスのコンストラクタを継承
super().__init__(name)
self.power = 3
class SuperCar(Car)といったように、子クラスの定義時に引数として親クラスを渡すことで継承ができます。継承することで、子クラスでは子クラスで定義したメソッドに加え、親クラスのメソッドも呼び出すことができます。
また、子クラスで親クラスのコンストラクタを呼び出して属性等を取得する場合はsuper()を用います。子クラスにおけるsuper().__init__(name)は親クラスの__init__()を呼び出しています。
今回はそのうえで子クラスのpowerを変更してみました。
この状態でそれぞれインスタンスを作成します。
if __name__ == "__main__":
car = Car("N Box")
print(car.name)
print("駆動方式: "+car.drive_system)
print("時間当たりの走行距離: "+str(car.run()))
print("-" * 20)
superCar = SuperCar("LaFerrari")
print(superCar.name)
print("駆動方式: "+superCar.drive_system)
print("時間当たりの走行距離: "+str(superCar.run()))
>>
N Box
駆動方式: FF
時間当たりの走行距離: 100
--------------------
LaFerrari
駆動方式: FF
時間当たりの走行距離: 300
superCarはCarクラスの定義情報も保持していることがわかります(drive_systemは定義していない)。また、SuperCarクラスで定義していないrun()メソッドも使えることがわかります。
まとめ
クラスの基本的な意味とPythonでの実装・挙動について見てきました。
オブジェクト指向は非常に難しく、筆者自身も理解しきれてはいませんが、少しずつ簡単なところから理解していくのが理解への近道だと思います。
クラスは特によく使うので、基本は押さえておきたいです。
ではでは👋