オブジェクト指向プログラミングの基礎
オブジェクト指向プログラミングの定義
オブジェクト指向プログラミングとは、プログラムをオブジェクトと呼ばれる個々の部品に分割し、それらを再利用可能で拡張可能な形で組み合わせるプログラミング手法です。オブジェクトはデータ(属性)と振る舞い(メソッド)を持っています。
クラスとオブジェクトの違い
クラスとは、オブジェクトの設計図のようなもので、オブジェクトの属性やメソッドを定義するために使用されます。オブジェクトは、クラスから生成されるインスタンスであり、クラスを実際に使用可能な形にしたものと言えます。
インスタンスと属性の概念
インスタンスは、クラスから生成されたオブジェクトのことを指します。インスタンスは、それぞれ独自の属性を持っています。属性は、インスタンスに関連するデータを表します。例えば、クラスが「人」である場合、属性には「名前」、「年齢」、「性別」などがあります。
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__は、オブジェクトの加算を定義するために使用されます。



コメント