クラス

Python

クラスは、オブジェクト指向プログラミングの基本的な概念の一つで、共通の特徴を持つオブジェクトを作成するための設計図となるものです。クラスは属性(変数)とメソッド(関数)を持ち、オブジェクトの状態を表現します。

クラスの定義

Pythonでは、classキーワードを使用してクラスを定義します。クラス名は慣習的にキャメルケース(単語の先頭を大文字にする)で表記します。また、クラスの属性やメソッドはインデントで区切られます。

class MyClass:
    # 属性の定義
    attribute1 = "Hello"
    attribute2 = 123

    # メソッドの定義
    def my_method(self):
        print("This is my method!")

クラス変数、インスタンス変数

Pythonでは、クラス内で使用される変数には2つの種類があります。それはクラス変数とインスタンス変数です。この記事では、それらの違いについて説明します。

クラス変数

クラス変数は、クラス内で宣言され、すべてのインスタンスで共有される変数です。すなわち、すべてのインスタンスが同じ値を参照することになります。クラス変数は、クラス名を用いてアクセスすることができます。

class MyClass:
    class_variable = 1
    
    def __init__(self, instance_variable):
        self.instance_variable = instance_variable
        
obj1 = MyClass(10)
obj2 = MyClass(20)

print(MyClass.class_variable)    # 1
print(obj1.class_variable)      # 1
print(obj2.class_variable)      # 1

上記の例では、class_variableというクラス変数が定義されています。このクラス変数は、クラス名を用いてアクセスすることができます。また、obj1obj2という2つのインスタンスが生成されています。これらのインスタンスからもクラス変数にアクセスすることができます。

インスタンス変数

インスタンス変数は、各インスタンスごとに異なる値を持つ変数です。すなわち、インスタンスごとに値が異なるため、別々の値を持つことができます。インスタンス変数は、selfを用いてアクセスすることができます。

class MyClass:
    class_variable = 1
    
    def __init__(self, instance_variable):
        self.instance_variable = instance_variable
        
obj1 = MyClass(10)
obj2 = MyClass(20)

print(obj1.instance_variable)    # 10
print(obj2.instance_variable)    # 20

上記の例では、instance_variableというインスタンス変数が定義されています。このインスタンス変数は、selfを用いてアクセスすることができます。また、obj1obj2という2つのインスタンスが生成されています。それぞれのインスタンスは、異なる値を持っています。

メソッド

メソッドとは、クラス内で定義された関数のことです。オブジェクトに対して行いたい処理を関数としてまとめ、その処理を行うための手段を提供します。

メソッドの定義

メソッドを定義するには、以下のようにクラス内で関数を定義します。以下の例では、クラスPerson内にintroduceメソッドを定義しています。このメソッドは、name属性を用いて自己紹介をするためのものです。

class Person:
    def __init__(self, name):
        self.name = name
    
    def introduce(self):
        print("こんにちは、私は{}です。".format(self.name))

メソッドの呼び出し

メソッドを呼び出すには、以下のようにオブジェクトの属性として指定します。以下の例では、Personクラスのインスタンスpersonintroduceメソッドを呼び出しています。

person = Person("太郎")
person.introduce()  # "こんにちは、私は太郎です。"と表示される

メソッドと引数

メソッドには、通常の関数同様に引数を指定することができます。以下の例では、Personクラス内にintroduce_withメソッドを定義しています。このメソッドは、他の人物と自己紹介をするためのもので、name引数を受け取ります。

class Person:
    def __init__(self, name):
        self.name = name
    
    def introduce(self):
        print("こんにちは、私は{}です。".format(self.name))
    
    def introduce_with(self, other):
        print("こんにちは、{}さん。私は{}です。".format(other.name, self.name))

introduce_withメソッドを呼び出すには、以下のように引数として他のPersonオブジェクトを指定します。

person1 = Person("太郎")
person2 = Person("花子")

person1.introduce_with(person2)  # "こんにちは、花子さん。私は太郎です。"と表示される

コンストラクタ

クラスのオブジェクトが作成された時に自動的に呼び出されるメソッドを、コンストラクタと呼びます。コンストラクタは、__init__という特別な名前のメソッドとして定義します。コンストラクタ内で、オブジェクトが持つ属性を初期化します。

class Person:
    # コンストラクタの定義
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # メソッドの定義
    def introduce(self):
        print(f"Hello, my name is {self.name} and I'm {self.age} years old.")

# オブジェクトの作成
person = Person("Alice", 30)

# メソッドの呼び出し
person.introduce()  # => "Hello, my name is Alice and I'm 30 years old."

デストラクタ

デストラクタは、メソッド名が __del__ であることを除けば、通常のメソッドと同じように定義されます。デストラクタは、self という引数を取りますが、通常は引数なしで定義されます。

以下の例を見てみましょう。

class MyClass:
    def __init__(self, name):
        self.name = name
        print(f'{self.name}が作成されました')

    def __del__(self):
        print(f'{self.name}が削除されました')


obj1 = MyClass('obj1')
obj2 = MyClass('obj2')
obj3 = obj1

del obj1
del obj2
del obj3

上記のコードでは、MyClassというクラスを定義しています。このクラスには、__init__メソッドと__del__メソッドがあります。__init__メソッドは、オブジェクトが作成されたときに実行され、__del__メソッドはオブジェクトが削除される前に実行されます。

オブジェクトの作成

クラスからオブジェクトを作成するには、クラス名に続けてカッコを付けて呼び出します。このとき、オブジェクトはクラスの属性やメソッドを継承します。

# オブジェクトの作成
my_object = MyClass()

# 属性の参照
print(my_object.attribute1)  # => "Hello"
print(my_object.attribute2)  # => 123

# メソッドの呼び出し
my_object.my_method()  # => "This is my method!"

継承

継承は、既存のクラスを拡張して、新しいクラスを定義する方法です。親クラス(基底クラスまたはスーパークラス)の属性やメソッドを引き継いで、子クラス(派生クラスまたはサブクラス)を定義します。

class Parent:
    def __init__(self, name):
        self.name = name
        
    def hello(self):
        print(f"Hello, {self.name}!")

class Child(Parent):
    def goodbye(self):
        print(f"Goodbye, {self.name}!")

上記の例では、Parent クラスに __init__ メソッドと hello メソッドを定義し、Child クラスは Parent クラスを継承しています。Child クラスは goodbye メソッドを定義していますが、hello メソッドを定義する必要はありません。Child クラスのインスタンスには name 属性があり、hello メソッドと goodbye メソッドの両方が呼び出せます。

parent = Parent("Alice")
child = Child("Bob")

parent.hello() # "Hello, Alice!"
child.hello()  # "Hello, Bob!"
child.goodbye() # "Goodbye, Bob!"

オーバーライド

オーバーライドは、親クラスのメソッドを子クラスで再定義することで、子クラスで独自の動作を実現する方法です。

class Parent:
    def hello(self):
        print("Hello, Parent!")

class Child(Parent):
    def hello(self):
        print("Hello, Child!")

上記の例では、Child クラスは Parent クラスを継承しています。しかし、Child クラスは Parent クラスの hello メソッドをオーバーライドし、異なる振る舞いをします。

parent = Parent()
child = Child()

parent.hello() # "Hello, Parent!"
child.hello()  # "Hello, Child!"

コメント