mei_13のPython講座 ロゴ

【解説】Pythonで学ぶ「オブジェクト指向」:プログラムを整理する魔法の考え方




Pythonで学ぶ「オブジェクト指向」:プログラムを整理する魔法の考え方


Hirokiのアイコン
【Hiroki】 Yukiさん、こんにちは。Pythonの基礎を少しずつ覚えてきたんですけど、最近「オブジェクト指向」という言葉をよく目にするようになりました。なんとなく難しそうな響きで、僕に理解できるか不安なんですけど……。


Yukiのアイコン
【Yuki】 Hirokiくん、こんにちは。そうですね……「オブジェクト指向」は、プログラミングを学ぶ上で一つの大きな山場だと言われることが多いかもしれません。でも、怖がらなくて大丈夫ですよ。一度コツを掴んでしまえば、複雑なプログラムも「整理整頓」しやすくなる、とても便利な考え方なんです。


Hirokiのアイコン
【Hiroki】 整理整頓ですか? プログラムを綺麗にするためのものなんですね。


Yukiのアイコン
【Yuki】 はい、その通りです。わたしも、誰かの役に立つために作られた小さなツールのお話などを聞くと、心が温かくなるのですが……オブジェクト指向も、実は「誰にとっても読みやすく、使いやすいプログラム」を作るための優しさから生まれたものだと、わたしは思っています。今日は一緒に、その仕組みをゆっくり紐解いていきましょう。

オブジェクト指向って、どんなもの?


Hirokiのアイコン
【Hiroki】 そもそも、「オブジェクト指向」の「オブジェクト」ってどういう意味なんですか?


Yukiのアイコン
【Yuki】 「オブジェクト(Object)」は、日本語で「」という意味です。オブジェクト指向プログラミングというのは、プログラムの中に登場するさまざまな要素を、まるで現実世界の「物」を扱うように組み立てていく手法のことなんです。


Hirokiのアイコン
【Hiroki】 プログラムを「物」として扱う……。ちょっとイメージしにくいです。


Yukiのアイコン
【Yuki】 例えば、RPG(ロールプレイングゲーム)を作ると想像してみてください。ゲームの中には「勇者」や「魔法使い」、「モンスター」が登場しますよね。これらを単なるデータの集まりとしてではなく、「名前」や「体力」といった属性(データ)と、「攻撃する」や「逃げる」といった振る舞い(処理)をセットにした「物」として定義するんです。


Hirokiのアイコン
【Hiroki】 なるほど。属性と振る舞いをセットにするのがポイントなんですね。


Yukiのアイコン
【Yuki】 ええ、その通りだと思います。バラバラだった変数と関数を、一つのまとまり(オブジェクト)に閉じ込めることで、どこで何が起きているのかが分かりやすくなるんです。

「設計図」と「実体」:クラスとインスタンス


Hirokiのアイコン
【Hiroki】 実際にPythonで書くときは、どうすればいいんですか?


Yukiのアイコン
【Yuki】 まず重要になるのが、「クラス」「インスタンス」という言葉です。よく「クラスは設計図」で、「インスタンスは設計図から作られた実物」に例えられます。


Hirokiのアイコン
【Hiroki】 設計図と実物、ですか。


Yukiのアイコン
【Yuki】 はい。例えば、犬をモデルにしたプログラムを考えてみましょう。まず「犬とはこういうものだ」という定義(クラス)を作り、そこから具体的な「ポチ」や「タロウ」という実体(インスタンス)を生み出します。コードで見ると、こんな感じになります。

# Dogクラス(設計図)の定義
class Dog:
    # 鳴くという振る舞い(メソッド)
    def bark(self):
        print("ワンワン!")

# インスタンス(実体)の作成
pochi = Dog()
pochi.bark()  # ポチが鳴く


Hirokiのアイコン
【Hiroki】 class Dog: と書くのが設計図なんですね。その下の pochi = Dog() で、実際に動く「ポチ」が作られているのが分かります。


Yukiのアイコン
【Yuki】 よく気づきましたね、Hirokiくん。この pochi という変数が、Dog クラスから生まれた「インスタンス」なんです。このように、共通のルールを持つものをたくさん作るのに向いています。

データの初期化:initメソッドの役割


Hirokiのアイコン
【Hiroki】 でも、今のコードだと、どんな犬でも「ワンワン!」としか言えないですよね。名前とか種類とか、個別のデータを持たせるにはどうすればいいんですか?


Yukiのアイコン
【Yuki】 そこで登場するのが、__init__(イニット)メソッドという特別な仕組みです。これは「コンストラクタ」とも呼ばれていて、インスタンスが作られた瞬間に自動的に実行される処理なんです。


Hirokiのアイコン
【Hiroki】 インスタンスを作るときに、初期設定をしてくれる機能ということですね。


Yukiのアイコン
【Yuki】 はい、その通りです。これを使うことで、インスタンスごとに異なるデータを持たせることができます。コードを書き換えてみましょう。

class Dog:
    # 初期化メソッド
    def __init__(self, name, breed):
        self.name = name    # 名前の属性
        self.breed = breed  # 犬種の属性

    def introduce(self):
        print(f"僕は{self.breed}の{self.name}だよ。")

# 異なるデータを持つインスタンスを作成
pochi = Dog("ポチ", "柴犬")
tama = Dog("タマ", "チワワ")

pochi.introduce()
tama.introduce()


Hirokiのアイコン
【Hiroki】 あ、self.name というのが出てきましたね。これって何ですか?


Yukiのアイコン
【Yuki】 self は、「自分自身」という意味なんです。クラスの中で「これは自分の持っているデータですよ」と指し示すために必要になります。最初は少し不思議に感じるかもしれませんが、「自分自身の属性を保存するための予約席」だと思っておけば大丈夫です……たぶん。


Hirokiのアイコン
【Hiroki】 予約席……分かりやすいです! インスタンスごとに namebreed が違うけど、同じ introduce メソッドが使えるのが便利ですね。

コードを再利用する:継承のしくみ


Hirokiのアイコン
【Hiroki】 もし、普通の犬だけじゃなくて、「働く犬(警察犬)」みたいな、もっと特別な機能を持ったクラスを作りたくなったら、また一から書かないといけないんですか?


Yukiのアイコン
【Yuki】 いいえ、そんなことはありません。オブジェクト指向には、「継承(Inheritance)」という素敵な仕組みがあるんです。すでにあるクラスの性質を引き継いで、新しいクラスを作ることができるんですよ。


Hirokiのアイコン
【Hiroki】 引き継ぎ! それなら手間が省けそうですね。


Yukiのアイコン
【Yuki】 はい。元のクラスを「親クラス(スーパークラス)」、新しく作るクラスを「子クラス(サブクラス)」と呼びます。例えば、先ほどの Dog クラスを継承して、WorkingDog クラスを作ってみましょう。

# Dogクラスを継承する
class WorkingDog(Dog):
    def work(self):
        print(f"{self.name}は一生懸命、パトロールをしています。")

# 子クラスのインスタンス作成
shepherd = WorkingDog("マックス", "シェパード")

# 親クラスのメソッドも使える
shepherd.introduce()
# 子クラス独自のメソッドも使える
shepherd.work()


Hirokiのアイコン
【Hiroki】 すごい! WorkingDog クラスの中には introduce メソッドを書いていないのに、ちゃんと動いていますね。


Yukiのアイコン
【Yuki】 そうなんです。親が持っている能力を子がそのまま受け継いでいるからなんです。こうすることで、同じようなコードを何度も書く必要がなくなります。これは、プログラムを「部品」として再利用しやすくするための工夫なんです。

情報を守る:カプセル化の考え方


Hirokiのアイコン
【Hiroki】 オブジェクト指向って、すごく効率的なんですね。


Yukiのアイコン
【Yuki】 そうですね。でも、それだけじゃないんです。もう一つ大切な考え方に、「カプセル化(Encapsulation)」というものがあります。これは、オブジェクトの中にある大事なデータを、外から勝手に書き換えられないように守る仕組みです。


Hirokiのアイコン
【Hiroki】 守る? プログラムにセキュリティみたいなものが必要なんですか?


Yukiのアイコン
【Yuki】 はい。例えば、ゲームのキャラクターの「HP(体力)」が、知らないうちにマイナスの値に書き換えられてしまったら困りますよね。Pythonでは、変数名の前にアンダースコアを2つ __ 付けることで、外から直接見えにくくすることができるんです。

class Character:
    def __init__(self, name, hp):
        self.name = name
        self.__hp = hp  # 外から見えないように隠す

    def take_damage(self, damage):
        self.__hp -= damage
        if self.__hp < 0:
            self.__hp = 0
        print(f"{self.name}の現在の体力は{self.__hp}です。")

hero = Character("勇者", 100)
hero.take_damage(20)

# 直接書き換えようとしてもエラーになる(または無視される)
# hero.__hp = 999 


Hirokiのアイコン
【Hiroki】 なるほど。専用のメソッド(今の例だと take_damage)を通してしかデータを操作できないようにすれば、変なデータが入るのを防げますね。


Yukiのアイコン
【Yuki】 その通りです。大事なものをカプセルに閉じ込めて保護する……。ちょっと内気なわたしには、共感できる考え方かもしれません……なんて。

柔軟な設計を:ポリモーフィズム


Hirokiのアイコン
【Hiroki】 だんだんオブジェクト指向のメリットが見えてきました。


Yukiのアイコン
【Yuki】 それは良かったです。最後に少しだけ、「ポリモーフィズム(多態性)」というお話もしておきますね。名前は少し難しそうですが、「同じ命令を出しても、相手によって振る舞いが変わる」という性質のことです。


Hirokiのアイコン
【Hiroki】 相手によって振る舞いが変わる?


Yukiのアイコン
【Yuki】 例えば、いろいろな動物のインスタンスがあったとします。それぞれに「鳴け」という命令(メソッド呼び出し)を送ったとき、犬なら「ワンワン」、猫なら「ニャー」と、それぞれの鳴き方で応えてくれる……。そんなイメージです。

class Cat:
    def speak(self):
        print("ニャー")

class Dog:
    def speak(self):
        print("ワンワン")

# 異なる種類の動物をリストにする
animals = [Cat(), Dog()]

for animal in animals:
    animal.speak() # 同じメソッド名なのに、結果が違う


Hirokiのアイコン
【Hiroki】 使う側は相手が誰か細かく気にしなくても、同じ名前のメソッド(speak)を呼ぶだけでいいんですね。これは便利そうです。


Yukiのアイコン
【Yuki】 はい。これによって、新しい動物が追加されても、呼び出す側のプログラムを書き換える必要がなくなります。拡張性がとても高くなるんですよ。

まとめ:オブジェクト指向でプログラムを「物語」にする


Hirokiのアイコン
【Hiroki】 Yukiさん、ありがとうございます! クラスやインスタンス、継承、カプセル化……。どれもプログラムを整理して、ミスを減らすための工夫なんですね。


Yukiのアイコン
【Yuki】 はい、その通りだと思います。最初は難しく感じるかもしれませんが、これらを使いこなせるようになると、プログラムを書くのがもっと楽しくなるはずです。バラバラの命令の羅列だったものが、まるで生き生きとした「世界」や「物語」のように感じられるようになるかもしれません。


Hirokiのアイコン
【Hiroki】 物語……なんだかワクワクしてきました。もっと使いこなせるように練習してみます。


Yukiのアイコン
【Yuki】 いい心がけですね、Hirokiくん。もし途中で分からなくなったら、またいつでも聞いてください。わたしは夜の方が調子がいいので、遅い時間でも大丈夫ですよ。


Hirokiのアイコン
【Hiroki】 あ、そういえばYukiさんは夜行性でしたね。僕ももう少し頑張ってみます!


Yukiのアイコン
【Yuki】 ふふっ、無理はしないでくださいね。Pythonの公式ドキュメントなども、時間があるときに覗いてみると、より深い知識が得られるかもしれません。

Python 公式ドキュメント:クラス


Yukiのアイコン
【Yuki】 冬の静かな夜は、プログラミングに集中するにはぴったりですから……一緒に、一歩ずつ進んでいきましょう。


Hirokiのアイコン
【Hiroki】 はい、よろしくお願いします、Yukiさん!



< 関数型プログラミング
コラム一覧に戻る
ツリー図 >

この記事では基礎を解説しましたが、実務においては「もっと複雑なデータを扱いたい」「独自のシステムに組み込みたい」といった、個別の課題に直面することも多いはずです。

「自分で書く時間は最小限に抑え、プロの品質でツールを完成させたい」という方は、ぜひ一度ご相談ください。

「教わる」だけでなく「形にする」パートナーとして、フリーランスエンジニアのmei_13が最短ルートでの解決をサポートします。

➡ ココナラで制作・相談を依頼する(見積もり無料)


初心者から始められるPythonレッスン

プログラミング未経験者・初心者歓迎!
月額4,000円で質問し放題!!
● 完全オンライン
● 翌日までには必ず返信
● 挫折しない独自の学習メソッド
● 圧倒的高評価!!
テキストベースで時間を選ばない
● 高品質なサンプルコード
詳細はこちら
興味がある方はまず質問だけでもどうぞ!



AIアシスタント Yuki