Pythonでクラスとオブジェクトを作成してOOPを理解する

Pythonの「クラス」は、オブジェクト指向プログラミング(OOP)の核となる機能であり、関連するデータ(属性)や処理(メソッド)をひとまとめにする仕組みです。

これにより、コードの再利用性や可読性を大幅に高めます。

本記事では、クラスの基本から応用までを中級者向けにクラスの基本概念からコード例、実際の使い方、最後に演習問題とその解答例まで、ステップごとに丁寧に解説します。


オブジェクト指向プログラミング(OOP)とは?

オブジェクト指向プログラミングは、「データ(属性)と処理(振る舞い)をひとまとめにして管理する」手法です。

従来の手続き型プログラミングでは、データと関数は別々に扱われますが、OOPでは関連するデータと処理を“オブジェクト”という単位でまとめられます。

メリット
  • コードの再利用性が高まる
  • プログラムの構造が明確になり、保守性が向上する
  • 大規模開発でチーム間の分担がしやすい

クラスとは何か?

クラスは「オブジェクトの設計図」にあたり、属性(データ)とメソッド(振る舞い)を定義し、実際に動くデータのまとまり(インスタンス)を生成するためのテンプレートです。

メリット
  • コードの再利用性向上
  • データと処理を一元管理
  • 大規模開発での構造化を促進

下記は属性もメソッドもない「空のクラス」ですが、Dogという名前で新しい型(クラス)が定義された状態です。

class Dog:
    pass

オブジェクト(インスタンス)とは?

オブジェクトはクラスを元に生成された「実体」です。クラスの設計をもとに、実際にメモリ上に配置される箱だとイメージしてください。

my_dog = Dog()
print(type(my_dog))  # <class '__main__.Dog'>

このようにDog()と書くことでDogクラスの“インスタンス(実体)”が作られ、変数my_dogに代入されます。


属性(アトリビュート)

属性はオブジェクトが持つデータです。例えば犬のオブジェクトなら「名前」「年齢」「種類(breed)」などが属性にあたります。

class Dog:
    def __init__(self, name, age, breed):
        self.name = name    # 名前属性
        self.age = age      # 年齢属性
        self.breed = breed  # 種類属性

上記のように、__init__メソッド内でself.<属性名>として定義します。


メソッド

メソッドはオブジェクトが持つ振る舞いです。オブジェクトに命令を出す関数だと考えてください。

class Dog:
    def __init__(self, name, age, breed):
        self.name = name
        self.age = age
        self.breed = breed

    def bark(self):
        print(f"{self.name}がワンと鳴きました!")

barkは犬オブジェクトが「吠える」動作を表現しています。


selfとは?

selfは「このオブジェクト自身」を指す予約語です。メソッド内で属性や他のメソッドにアクセスするときに使います。

def greet(self):
    print(f"こんにちは、私は{self.name}です。年齢は{self.age}歳です。")

クラスの基本構文

クラス名は大文字で始めるのが慣例です。

__init__ メソッドは、インスタンス生成時に自動で呼ばれる特殊なメソッドです。初期化処理に使用します。

クラス定義
class クラス名:
    """クラスの説明(ドキュメンテーション)"""
    属性1 = 初期値  # クラス変数(全インスタンスで共有)
    
    def __init__(self, 引数1, 引数2):
        """コンストラクタ:インスタンス生成時に自動実行"""
        self.属性2 = 引数1  # インスタンス変数
        self.属性3 = 引数2

    def メソッド名(self, 引数):
        """インスタンスメソッド"""
        # 処理内容
        return 処理結果
インスタンス生成
obj = クラス名(値1, 値2)
属性とメソッドの呼び出し
obj.属性1
obj.メソッド名(引数)

コンストラクタとインスタンス変数

コンストラクタとは、クラスのインスタンス(オブジェクト)が生成される際に自動的に呼び出され、そのオブジェクトの初期化処理を行う特殊メソッドのことを指します。

alice と bob は同じ設計図から作られた別々の箱です。

それぞれの name と age は独立して保持されます。

class Person:
    def __init__(self, name, age):
        self.name = name  # インスタンスごとに固有
        self.age = age

alice = Person("Alice", 30)
bob   = Person("Bob", 25)

print(alice.name, alice.age)  # Alice 30
print(bob.name,   bob.age)    # Bob 25

メソッドの定義と呼び出し

increment() で内部データを更新し、show() で表示

メソッドを通じて属性を操作することで安全にデータを扱える

class Counter:
    def __init__(self):
        self.count = 0

    def increment(self):
        self.count += 1

    def show(self):
        print(f"現在のカウント: {self.count}")

c = Counter()
c.increment()
c.increment()
c.show()  # 現在のカウント: 2

実践的なサンプル:銀行口座クラス

デフォルト引数で初期残高を指定し、入金・出金メソッドで口座残高を更新しています。

class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner   = owner
        self.balance = balance

    def deposit(self, amount):
        self.balance += amount
        print(f"{amount}円入金しました。残高: {self.balance}円")

    def withdraw(self, amount):
        if amount > self.balance:
            print("残高不足です。")
        else:
            self.balance -= amount
            print(f"{amount}円出金しました。残高: {self.balance}円")

# 使い方
acc = BankAccount("Tanaka", 1000)
acc.deposit(500)    # 500円入金しました。残高: 1500円
acc.withdraw(2000)  # 残高不足です。
acc.withdraw(300)   # 300円出金しました。残高: 1200円

まとめ

  • クラスは「設計図」、インスタンスは「実体」である
  • __init__ で初期化、self で属性・メソッドにアクセス
  • メソッドで属性を安全に操作できる

演習問題

  1. 本棚クラス(Bookshelf)を作成
    • 属性:books (初期は空リスト)
    • メソッド:
      • add_book(title):タイトルをリストに追加
      • remove_book(title):リストから削除(存在しない場合はメッセージ表示)
      • list_books():現状の本のタイトルをすべて表示
  2. テスト用インスタンスを作成し、以下を実行
    • 本を3冊追加
    • 1冊削除
    • 現在の本一覧を表示

解答例

class Bookshelf:
    def __init__(self):
        self.books = []

    def add_book(self, title):
        self.books.append(title)
        print(f"「{title}」を追加しました。")

    def remove_book(self, title):
        if title in self.books:
            self.books.remove(title)
            print(f"「{title}」を削除しました。")
        else:
            print(f"「{title}」は見つかりませんでした。")

    def list_books(self):
        if not self.books:
            print("本棚に本はありません。")
        else:
            print("本棚の中身:")
            for idx, book in enumerate(self.books, start=1):
                print(f"{idx}. {book}")

# テスト
shelf = Bookshelf()
shelf.add_book("Python入門")
shelf.add_book("データサイエンス基礎")
shelf.add_book("機械学習アルゴリズム")
shelf.remove_book("データサイエンス基礎")
shelf.list_books()
実行結果例
「Python入門」を追加しました。
「データサイエンス基礎」を追加しました。
「機械学習アルゴリズム」を追加しました。
「データサイエンス基礎」を削除しました。
本棚の中身:
1. Python入門
2. 機械学習アルゴリズム

以上が「Pythonのクラスとオブジェクトの作成」の記事です。この記事を参考に、ぜひ自分でもクラスを試しながら理解を深めてみてください!