6. オブジェクト指向プログラミング
- クラスとオブジェクト
- カプセル化
- 継承
- ポリモーフィズム
- 抽象クラスとインターフェース
オブジェクト指向プログラミング(OOP)は、プログラミングのパラダイムの一つで、データとそのデータを操作する機能を一つの「オブジェクト」としてまとめる考え方です。Pythonはオブジェクト指向プログラミングをサポートしており、その概念を効果的に活用できます。以下、OOPの主要な概念について、Pythonのサンプルコードを交えて説明します。
1. クラスとオブジェクト
クラスは、オブジェクトの設計図やテンプレートのようなものです。オブジェクトは、クラスのインスタンス(実体)です。
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
return f"{self.name}が吠えました:ワン!"
# オブジェクトの作成
my_dog = Dog("ポチ", 3)
print(my_dog.name) # ポチ
print(my_dog.bark()) # ポチが吠えました:ワン!
この例では、Dog
というクラスを定義し、name
とage
という属性、そしてbark
というメソッドを持たせています。
2. カプセル化
カプセル化は、データ(属性)と、そのデータを操作するメソッドをまとめることです。また、データの直接アクセスを制限することで、データの整合性を保護します。
class BankAccount:
def __init__(self, balance):
self.__balance = balance # プライベート属性
def deposit(self, amount):
if amount > 0:
self.__balance += amount
return True
return False
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
return True
return False
def get_balance(self):
return self.__balance
account = BankAccount(1000)
print(account.get_balance()) # 1000
account.deposit(500)
print(account.get_balance()) # 1500
account.withdraw(200)
print(account.get_balance()) # 1300
# print(account.__balance) # これはエラーになります
この例では、__balance
をプライベート属性とし、直接アクセスできないようにしています。代わりに、deposit
、withdraw
、get_balance
メソッドを通じて残高を操作・取得します。
3. 継承
継承は、既存のクラス(親クラス)の属性やメソッドを新しいクラス(子クラス)に引き継ぐ機能です。
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
class Dog(Animal):
def speak(self):
return f"{self.name}が吠えました:ワン!"
class Cat(Animal):
def speak(self):
return f"{self.name}が鳴きました:ニャー!"
dog = Dog("ポチ")
cat = Cat("タマ")
print(dog.speak()) # ポチが吠えました:ワン!
print(cat.speak()) # タマが鳴きました:ニャー!
この例では、Animal
クラスを親クラスとし、Dog
とCat
クラスがそれを継承しています。各子クラスはspeak
メソッドをオーバーライド(再定義)しています。
4. ポリモーフィズム
ポリモーフィズムは、同じインターフェース(メソッド名)で異なる挙動を実現する機能です。
def animal_sound(animal):
print(animal.speak())
dog = Dog("ポチ")
cat = Cat("タマ")
animal_sound(dog) # ポチが吠えました:ワン!
animal_sound(cat) # タマが鳴きました:ニャー!
この例では、animal_sound
関数はAnimal
クラスのインスタンスを期待していますが、実際にはDog
やCat
のインスタンスを渡しても正しく動作します。これがポリモーフィズムの一例です。
5. 抽象クラスとインターフェース
抽象クラスは、直接インスタンス化されることを意図していないクラスで、他のクラスが継承して使用することを前提としています。Pythonでは、abc
モジュールを使用して抽象クラスを定義できます。
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
# shape = Shape() # これはエラーになります
rectangle = Rectangle(5, 3)
circle = Circle(2)
print(rectangle.area()) # 15
print(circle.area()) # 12.56
この例では、Shape
は抽象クラスで、area
メソッドを持つことを要求しています。Rectangle
とCircle
クラスはShape
を継承し、それぞれarea
メソッドを実装しています。
これらの概念を理解し、適切に使用することで、より構造化され、保守性の高い、再利用可能なコードを書くことができます。オブジェクト指向プログラミングは、大規模なプロジェクトや複雑なシステムの設計に特に有効です。