オブジェクト指向プログラミングの基礎
オブジェクト指向プログラミングの定義
オブジェクト指向プログラミングとは、プログラムをオブジェクトと呼ばれる個々の部品に分割し、それらを再利用可能で拡張可能な形で組み合わせるプログラミング手法です。オブジェクトはデータ(属性)と振る舞い(メソッド)を持っています。
クラスとオブジェクトの違い
クラスとは、オブジェクトの設計図のようなもので、オブジェクトの属性やメソッドを定義するために使用されます。オブジェクトは、クラスから生成されるインスタンスであり、クラスを実際に使用可能な形にしたものと言えます。
インスタンスと属性の概念
インスタンスは、クラスから生成されたオブジェクトのことを指します。インスタンスは、それぞれ独自の属性を持っています。属性は、インスタンスに関連するデータを表します。例えば、クラスが「人」である場合、属性には「名前」、「年齢」、「性別」などがあります。
Pythonのクラスとオブジェクト
Pythonでのクラスの定義方法
Pythonでクラスを定義するには、class
キーワードを使用します。以下は、クラスの定義例です。
class MyClass:
pass
上記の例では、MyClass
というクラスを定義しています。pass
は何もしない文ですが、クラス内には少なくとも1つの文が必要なため、文を書かない場合はpass
を使用することがあります。
オブジェクトを生成する方法
クラスからオブジェクトを生成するには、クラス名に括弧をつけて呼び出します。
my_object = MyClass()
上記の例では、MyClass
クラスからmy_object
というオブジェクトを生成しています。このオブジェクトは、クラスの属性やメソッドを継承します。
クラス属性とインスタンス属性の違い
クラス属性とは、クラスに属する属性のことで、全てのインスタンスで共有されます。インスタンス属性とは、各インスタンスに属する属性のことで、各インスタンスごとに独自の値を持ちます。以下は
クラス属性とインスタンス属性の違いを示す例です。
class MyClass:
class_attribute = 0
def __init__(self, instance_attribute):
self.instance_attribute = instance_attribute
# クラス属性へのアクセス
print(MyClass.class_attribute) # 0
# インスタンス属性へのアクセス
my_object1 = MyClass(1)
print(my_object1.instance_attribute) # 1
my_object2 = MyClass(2)
print(my_object2.instance_attribute) # 2
# クラス属性へのアクセス
print(my_object1.class_attribute) # 0
print(my_object2.class_attribute) # 0
上記の例では、class_attribute
はクラス属性で、instance_attribute
はインスタンス属性です。クラス属性はMyClass
クラス全体で共有されるため、my_object1
やmy_object2
の値が変更されたとしても、class_attribute
の値は変わりません。
Pythonの継承
継承とは何か
継承とは、あるクラスが持つ属性やメソッドを、別のクラスが引き継ぐことができる機能のことです。継承元のクラスを親クラス、継承先のクラスを子クラスと呼びます。
Pythonでの継承の実装方法
Pythonでは、子クラスの定義時に親クラスを指定することで継承を実現します。以下は、継承の例です。
class MyParentClass:
def parent_method(self):
print('Parent Method')
class MyChildClass(MyParentClass):
def child_method(self):
print('Child Method')
child_object = MyChildClass()
child_object.parent_method() # 'Parent Method'
child_object.child_method() # 'Child Method'
上記の例では、MyParentClass
という親クラスと、MyChildClass
という子クラスを定義しています。子クラスは、MyParentClass
のparent_method
メソッドを継承しています。
親クラスと子クラスの関係
子クラスは、親クラスの属性やメソッドを継承するため、親クラスとの関係性があります。以下は、親クラスと子クラスの関係性を示す例です。
class MyParentClass:
def parent_method(self):
print('Parent Method')
class MyChildClass(MyParentClass):
def child_method(self):
print('Child Method')
child_object = MyChildClass()
print(isinstance(child_object, MyChildClass)) # True
print(isinstance(child_object, MyParentClass)) # True
上記の例では、isinstance
関数を使用して、child_object
がMyChildClass
クラスのインスタンスであること、MyParentClass
クラスのインスタンスであることを確認しています。MyChildClass
は、MyParentClass
を継承しているため、child_object
は両方のクラスのインスタンスであると言えます。
メソッド
メソッドとは何か
メソッドとは、クラスに定義された関数のことで、クラスの属性を操作するために使用されます。メソッドは、クラスメソッドとインスタンスメソッドの2種類があります。
Pythonでのメソッドの定義方法
Pythonでクラスメソッドを定義するには、@classmethod
デコレータを使用します。インスタンスメソッドを定義するには、通常の関数定義と同じように、第一引数にself
を指定します。以下は、メソッドの定義例です。
class MyClass:
class_attribute = 0
def __init__(self, instance_attribute):
self.instance_attribute = instance_attribute
# インスタンスメソッドの定義
def instance_method(self):
print('This is instance method')
# クラスメソッドの定義
@classmethod
def class_method(cls):
print('This is class method')
上記の例では、MyClass
クラスに、instance_method
とclass_method
という2つのメソッドを定義しています。instance_method
はインスタンスメソッドであり、class_method
はクラスメソッドです。
クラスメソッドとインスタンスメソッドの違い
クラスメソッドとインスタンスメソッドの違いは、第一引数に渡されるオブジェクトが異なる点です。インスタンスメソッドは、メソッドを呼び出すインスタンス自身が第一引数に渡されます。一方、クラスメソッドは、クラス自身が第一引数に渡されます。
以下は、クラスメソッドとインスタンスメソッドの違いを示す例です。
class MyClass:
class_attribute = 0
def __init__(self, instance_attribute):
self.instance_attribute = instance_attribute
# インスタンスメソッドの定義
def instance_method(self):
print(f'This is instance method. instance_attribute: {self.instance_attribute}')
# クラスメソッドの定義
@classmethod
def class_method(cls):
print(f'This is class method. class_attribute: {cls.class_attribute}')
上記の例では、instance_method
はインスタンスメソッドであり、class_method
はクラスメソッドです。instance_method
では、第一引数にself
が指定されており、self.instance_attribute
でインスタンスの属性にアクセスしています。一方、class_method
では、第一引数にcls
が指定されており、cls.class_attribute
でクラスの属性にアクセスしています。
以下は、メソッドを呼び出す例です。
my_object = MyClass(1)
my_object.instance_method() # 'This is instance method. instance_attribute: 1'
MyClass.class_method() # 'This is class method. class_attribute: 0'
上記の例では、my_object
というインスタンスからinstance_method
を呼び出しています。また、MyClass
クラスからclass_method
を呼び出しています。
ポリモーフィズム
ポリモーフィズムとは何か
ポリモーフィズムとは、異なるクラスが同じインターフェースを実装することで、同じメソッド名で異なる処理を行うことができる機能のことです。
Pythonでのポリモーフィズムの実現方法
Pythonでは、多様なオブジェクトを同じインターフェースで扱うことができるため、ポリモーフィズムを実現しやすいです。
以下は、ポリモーフィズムの例です。
class Dog:
def sound(self):
print('Bow-wow')
class Cat:
def sound(self):
print('Meow')
class AnimalSound:
def __init__(self, animal):
self.animal = animal
def make_sound(self):
self.animal.sound()
dog = Dog()
animal_sound = AnimalSound(dog)
animal_sound.make_sound() # 'Bow-wow'
cat = Cat()
animal_sound = AnimalSound(cat)
animal_sound.make_sound() # 'Meow'
上記の例では、Dog
クラスとCat
クラスがsound
メソッドを持っています。AnimalSound
クラスは、make_sound
メソッドを持っており、渡されたオブジェクトのsound
メソッドを呼び出しています。AnimalSound
クラスは、Dog
クラスやCat
クラスなど、sound
メソッドを持つオブジェクトならどんなオブジェクトでも受け取ることができます。
カプセル化
カプセル化とは何か
カプセル化とは、オブジェクトの内部の詳細を隠蔽することで、外部からの不正なアクセスを防ぎ、オブジェクトの安全性を高める機能のことです。Pythonでは、アンダースコア2つ(__
)で始まる名前を持つ属性やメソッドを定義することで、カプセル化を実現します。
Pythonでのカプセル化の実現方法
以下は、カプセル化の例です。
class MyClass:
def __init__(self, value):
self.__value = value
def __hidden_method(self):
print('This is hidden method')
def public_method(self):
print(f'Value: {self.__value}')
self.__hidden_method()
my_object = MyClass(1)
my_object.public_method() # 'Value: 1', 'This is hidden method'
# 外部から直接アクセスするとAttributeErrorが発生する
print(my_object.__value) # AttributeError: 'MyClass' object has no attribute '__value'
my_object.__hidden_method() # AttributeError: 'MyClass' object has no attribute '__hidden_method'
上記の例では、MyClass
クラスに、__value
と__hidden_method
という2つの非公開属性やメソッドを定義しています。public_method
は、__value
の値を表示し、__hidden_method
を呼び出します。外部からは、__value
や__hidden_method
に直接アクセスすることはできず、AttributeErrorが発生します。
抽象化
抽象化とは何か
抽象化とは、現実世界のオブジェクトの本質的な特徴や動作を表現し、それをプログラムに取り込むことで、プログラムの抽象度を高めることを指します。Pythonでは、抽象クラスを定義することで、抽象化を実現します。
Pythonでの抽象化の実現方法
以下は、抽象化の例です。
from abc import ABC, abstractmethod
class AbstractClass(ABC):
@abstractmethod
def abstract_method(self):
pass
class MyClass(AbstractClass):
def abstract_method(self):
print('This is abstract method')
my_object = MyClass()
my_object.abstract_method() # 'This is abstract method'
# AbstractClassを直接インスタンス化するとTypeErrorが発生する
# TypeError: Can't instantiate abstract class AbstractClass with abstract methods abstract_method
my_abstract_object = AbstractClass()
上記の例では、AbstractClass
という抽象クラスを定義しています。抽象クラスは、@abstractmethod
デコレータを付けた抽象メソッドを持ちます。MyClass
クラスは、AbstractClass
を継承しており、抽象メソッドを実装しています。MyClass
クラスをインスタンス化することで、抽象メソッドが呼び出されます。AbstractClass
を直接インスタンス化することはできないため、TypeErrorが発生します。
特殊メソッド
特殊メソッドとは何か
特殊メソッドとは、Pythonのオブジェクトが持つ特殊な機能を実現するためのメソッドのことです。特殊メソッドは、アンダースコア2つで囲まれた名前を持ちます。
Pythonでの特殊メソッドの実装方法
以下は、特殊メソッドの例です。
class MyClass:
def __init__(self, value):
self.value = value
def __str__(self):
return f'MyClass({self.value})'
def __add__(self, other):
return MyClass(self.value + other.value)
my_object1 = MyClass(1)
my_object2 = MyClass(2)
# __str__メソッドによって、オブジェクトの文字列表現が表示される
print(my_object1) # 'MyClass(1)'
# __add__メソッドによって、オブジェクトの加算が行われる
my_object3 = my_object1 + my_object2
print(my_object3) # 'MyClass(3)'
上記の例では、MyClass
クラスに、__str__
と__add__
という2つの特殊メソッドを定義しています。__str__
は、オブジェクトの文字列表現を返すために使用されます。__add__
は、オブジェクトの加算を定義するために使用されます。
コメント