クラス: オブジェクト指向の基礎

データと振る舞いをまとめる。大規模開発に必須。

クラス
データと振る舞いをまとめた設計図。
インスタンス
クラスから作られたオブジェクト。
self
インスタンス自身を指す。

なぜクラスが必要か?

クラスは「データ」と「振る舞い(メソッド)」を一つにまとめる仕組みです。例えば、ユーザー情報(名前、年齢)とその操作(年齢を増やす、名前を取得する)を別々に管理すると、データと操作が不一致になるリスクがあります。クラスを使うと、データと操作をセットにして管理できるため、コードが読みやすく、保守しやすくなります。また、オブジェクト指向プログラミングでは、カプセル化(private属性)によってデータを保護し、外部からの不正なアクセスを防げます。

いつ使うか?

クラスは、以下のような場面で使います: 1. **データと振る舞いをセットにしたいとき**: ユーザー、商品、注文など、データとそれを操作するメソッドを一つにまとめたいとき。 2. **再利用性を高めたいとき**: 同じ設計図(クラス)から、複数のオブジェクト(インスタンス)を作成できる。 3. **カプセル化が必要なとき**: データを直接触らせず、メソッドを通して操作させたいとき。 4. **継承を活用したいとき**: 既存のクラスの機能を拡張して、新しいクラスを作りたいとき。

実践テクニック

dataclassを使う

Python 3.7以降では、`dataclass` デコレータを使うと、クラスを簡潔に定義できます。`dataclass` を使うと、`__init__`、`__repr__`、`__eq__`、`__hash__` などの特殊メソッドが自動生成されるため、ボイラープレートコードを大幅に削減できます。また、型ヒントやデフォルト値の設定も簡単になります。

プロパティを使う

Pythonでは、`@property` デコレータを使うと、ゲッター/セッターを定義できます。これにより、属性へのアクセスをカスタマイズでき、バリデーションや計算ロジックを追加できます。ただし、過度に使うとコードが複雑になるため、シンプルなゲッター/セッターを使うことを推奨します。

特殊メソッドを活用する

Pythonには、クラスの振る舞いをカスタマイズするための特殊メソッド(dunderメソッド)があります。`__str__`、`__repr__`、`__len__` などを使うと、オブジェクトの文字列表現や比較ロジックをカスタマイズできます。これらのメソッドを適切に使うと、より直感的なAPIを提供できます。

継承とコンポジションの使い分け

オブジェクト指向プログラミングでは、「継承(Inheritance)」と「コンポジション(Composition)」の2つのアプローチがあります。継承は「is-a」関係(犬は動物である)のような階層構造をモデル化するのに適しています。一方、コンポジションは「has-a」関係(車はエンジンを持っている)のような機能の組み合わせをモデル化するのに適しています。Pythonでは、複数継承よりもコンポジションやミックスインを推奨するケースが多いです。

クラスとは?

建築の設計図 (Architectural Blueprint)

クラスは「家の設計図(Blueprint)」です。設計図そのものには人は住めません。設計図を元に建てた「実際の家」がインスタンス(オブジェクト)です。1つの設計図から、全く同じ構造だけど、住所や表札(データ)が違う家を何軒でも建てることができます。

関数が「処理」をまとめるものなら、クラスは「データ(属性)」と「処理(メソッド)」をセットでまとめるものです。「ユーザー」や「商品」といった概念をコード上で定義するのに使います。

Basic Class
class User:
def __init__(self, name: str, age: int):
self.name = name
self.age = age
def greet(self) -> str:
return f"Hi, I'm {self.name}"
def __repr__(self) -> str:
return f"User(name={self.name!r}, age={self.age})"
alice = User("Alice", 30)
print(alice.greet()) # Hi, I'm Alice
Bad
# ❌ Bad: 辞書で代用
user = {"name": "Alice", "age": 30}
# 型チェックなし、補完なし、構造が不明確
Good
# ✅ Good: dataclass で簡潔に
from dataclasses import dataclass
@dataclass
class User:
name: str
age: int
# __init__, __repr__, __eq__ が自動生成

継承

Inheritance
class Animal:
def __init__(self, name: str):
self.name = name
def speak(self) -> str:
raise NotImplementedError
class Dog(Animal):
def speak(self) -> str:
return f"{self.name} says Woof!"
class Cat(Animal):
def speak(self) -> str:
return f"{self.name} says Meow!"
dog = Dog("Rex")
print(dog.speak()) # Rex says Woof!

合格ライン

クラスを定義できる
@dataclass を使える

演習課題

課題1: クラス定義
__init__ でフィールドを初期化するクラスを作成してください。
課題2: @dataclass
@dataclass でデータクラスを作成してください。

参考文献

この記事は以下の公的ガイドライン/標準に基づいています。