【Python】レッスン5-05:クラスの継承を理解しよう

ながみえ
【Python学習記事のアイキャッチ画像】Lesson5-5 クラスの継承を理解しよう

一つ前のLessonではプロパティについて学習しました。

今回はクラスの継承について見ていきましょう。

Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:関数とスコープ編

Lesson4:データ構造編
Lesson5:オブジェクト指向編
・Lesson5-1:クラスの基本を理解しよう
・Lesson5-2:メソッドの基本を理解しよう
・Lesson5-3:カプセル化を理解しよう
・Lesson5-4:プロパティを理解しよう
・Lesson5-5:クラスの継承を理解しよう ◁今回はココ
・Lesson5-6:メソッドのオーバーライドを理解しよう
・Lesson5-7:静的メソッドを理解しよう
・Lesson5-8:モジュールを使いこなそう
・Lesson5-9:抽象クラスを理解しよう
・Lesson5-10:ミックスインを理解しよう
・Lesson5-11:データクラスを理解しよう
・練習問題5-1:モンスター捕獲ゲームを作ろう
・練習問題5-2:モンスターとのバトルゲームを作ろう
次のステップ:Python基礎習得者にお勧めの道5選(実務or副業)

<<前のページ

【Python学習記事のアイキャッチ画像】Lesson5-4 プロパティを理解しよう

Pythonの記事一覧

Python学習カテゴリの親ページ用アイキャッチ画像(テキスト&問題集)、記事一覧へのリンク案内

次のページ>>

【Python学習記事のアイキャッチ画像】Lesson5-6 メソッドのオーバーライドを理解しよう

継承とは|親クラスの機能を子クラスに受け継ぐ方法

継承は、親クラスの属性・メソッドを子クラスに受け継ぎ、共通処理をまとめつつ“差分だけ”を追加・変更できる仕組みです。

これを身につけると重複の少ないクラス設計ができ、既存コードを壊さずに振る舞いを拡張(オーバーライド/super())し、規模が大きくなっても保守しやすい構成にできます。

あなたのクラス設計力を一段引き上げましょう。

【Python】勉強猫がノートパソコンを前にして学習を始める様子。記事内の学習スタート用イラスト

クラスの継承の概要と使用するメリット

継承を使うことで、親クラスに定義されたメソッドや属性を子クラスが引き継ぐことができます。

子クラスは親クラスのすべての機能をそのまま利用できるだけでなく、必要に応じて独自のメソッドや属性を追加したり、親クラスのメソッドを変更することも可能です。

これにより、新しい機能を柔軟に追加しながらも、既存のコードを最大限に活用することができます。

クラスを継承するには、以下のように記述します。

class 親クラス名:
  	# 継承させたい属性

class 子クラス名(親クラス名):
  	# 子クラスの独自属性

クラスの継承を使うことで、以下のようなメリットが得られます。

  1. コードの再利用
    親クラスに一度定義したメソッドや属性は、子クラスで再利用できるため、重複コードを減らすことができます。
  2. 保守性の向上
    親クラスのコードを修正すると、その変更がすべての子クラスにも自動的に反映されるため、メンテナンスが容易になります。
  3. 拡張性の確保
    子クラスで独自の機能を追加することができるため、新しい機能を柔軟に追加できます。

これらの特徴を活用することで、効率的なプログラム設計が可能となります。

クラスの継承のサンプルコード

以下はクラスの継承を実際に使った例です。

この例ではAnimalという親クラスを定義し、そのクラスを継承する子クラスDogを作成しています。

# 親クラスの定義
class Animal:	# Animalクラスを定義(親クラス)
    def __init__(self, name):	# コンストラクタの定義
        self.name = name
    def speak(self):	# 継承させたいメソッド speak の定義
        print(f"{self.name}が吠えています")

# 子クラスの定義
class Dog(Animal):	# Animalクラスを継承したDogクラスを定義
    # 親クラスのコンストラクタを使用できるため、ここでは定義しない
    def run(self):	# このクラスの独自メソッド run の定義
        print(f"{self.name}が走っています")
        
class Cat(Animal):		# Animalクラスを継承したCaクラスを定義
    def sleep(self):	# このクラスの独自メソッド sleep の定義
        print(f"{self.name}が眠っています")

# インスタンス生成
dog = Dog("ポチ")	  # 引数ポチを渡してインスタンス生成
dog.speak()			# 親クラスのメソッドを呼び出し
dog.run()			# 子クラスの独自メソッドを呼び出し
cat = Cat("ミケ")	  # 引数ミケを渡してインスタンス生成
cat.speak()			# 親クラスのメソッドを呼び出し
cat.sleep()			# 子クラスの独自メソッドを呼び出し

このコードではAnimalクラスが基本的な属性nameとメソッドspeakを持っています。

DogクラスはAnimalクラスを継承し、親クラスの__init__メソッドを利用してname属性を初期化しますが、speakメソッドを独自に定義し直しています。

このように継承を使うことで親クラスの機能を再利用しつつ、子クラスに固有の振る舞いを追加することができます。

なお、今回は子クラスにコンストラクタを指定しませんでしたが、指定することも可能です。

ただし、その場合は親クラスのコンストラクタが自動で呼び出されなくなるため、super()関数 を用いて明示的に呼び出す必要があります。

class Dog(Animal):						# Animalクラスを継承したDogクラスを定義
    def __init__(self, name, breed):	# 子クラス独自の引数を追加したコンストラクタ
        super().__init__(name)			# 親クラスのコンストラクタを呼び出す
        self.breed = breed				# 子クラス独自の属性を追加

まとめ|親の力を生かし、差分で拡張しよう

【初心者向け】Pythonのオブジェクト指向を分かりやすくまとめた概念図。 特にクラスの継承、オーバーライド、抽象クラス、ミックスインクラス、データクラス、静的メソッドの関係性を視覚的に理解できるようまとめている。

継承は「親クラスの属性・メソッドを受け継ぎ、子クラスで差分だけを追加・変更する」仕組みでした。

共通化によるコード再利用、振る舞いの拡張、保守性の向上が主なメリットです。

今日身につけた「共通化と拡張」の視点は、この先の学習や実装でも確かな武器になります。

次のレッスンでも視野を広げていきましょう。

Q
サイト改善アンケート|ご意見をお聞かせください(1分で終わります)

本サイトでは、みなさまの学習をよりサポートできるサービスを目指しております。
そのため、みなさまの「プログラミングを学習する理由」などをアンケート形式でお伺いしています。

1分だけ、ご協力いただけますと幸いです。

【Python】サイト改善アンケート
1.このサイトをどのように活用していますか?また、今後どのように活用したいですか?
5.気になっているサービス・商品があれば教えてください。
(複数選択可)
※ 特定の記事に関する内容の場合は、記事番号(Python Lesson〇-〇)をご記入願います。 また、ご質問はここではなく問い合わせフォームからお願いします。

練習問題:クラスの継承を使ってみよう

この記事で学習した「クラスの継承」を復習する練習問題に挑戦しましょう。

【Python】勉強猫がノートパソコンに向かい、練習問題に挑戦する様子。記事内の休憩用イラスト

問題|車両クラスでオブジェクト指向を学ぼう

クラス継承を使った車両管理プログラムを作成しましょう。

親クラス「Vehicle」を定義し、その子クラスとして「Car」と「Motorcycle」を作成します。

各クラスは共通のメソッドを持ちつつ、固有の動作を追加します。プログラムでは車両の名前を設定し、対応する動作を実行するようにしてください。

以下の要件に従ってコードを完成させてください。

  • 親クラス「Vehicle」を定義し、名前を設定するコンストラクタと名前を表示するメソッドを作成すること。
  • 子クラス「Car」を「Vehicle」から継承し、車が走るメソッドを追加すること。
  • 子クラス「Motorcycle」を「Vehicle」から継承し、バイクが走るメソッドを追加すること。
  • 「Car」と「Motorcycle」クラスのオブジェクトを生成し、それぞれの動作を実行すること。

ただし、以下のような実行結果となるコードを書くこと。

この乗り物はトヨタです。
この乗り物はハーレーです。
トヨタが道路を走っています。
ハーレーが高速道路を疾走しています。

ヒント|難しいと感じる人だけ見よう

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

Q
ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)

1:親クラス「Vehicle」を定義し、名前の初期化と自己紹介の共通処理を用意
 ・親クラスに共通のデータと共通の振る舞いをまとめる発想で設計しよう。
 ・コンストラクタで受け取った値を、インスタンスの属性として保存できているかを確認しよう。
 ・表示用メソッドは、保存した属性を参照して定型文を組み立てるだけにすると分かりやすい。

2:子クラス「Car」「Motorcycle」を継承で定義し、固有の走行動作を追加
 ・子クラスは「親を括弧に書く」だけで継承でき、親の属性やメソッドをそのまま使える。
 ・固有メソッドは「そのクラスらしい動作」を1つ追加するイメージで考える。
 ・親の初期化がそのまま使える場合、子で新たに初期化を定義する必要はない。

3:インスタンスを生成し、継承メソッドと固有メソッドを順に呼び出して動作を確認
 ・子クラスからオブジェクトを作るときに、名前を引数として渡す。
 ・親のメソッドは、子クラスのオブジェクトからそのまま呼び出せる。
 ・実行結果例の並びに合わせて、紹介 → 紹介 → 車の走行 → バイクの走行の順で呼ぶ。

Q
ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

# 親クラス(Vehicle)の定義
class Vehicle:
    def __init__(self, name):	# コンストラクタで車両の名前を設定
        self.name = name
    def introduce(self):	# 親クラスのメソッド: 車両の名前を表示
        print(f"この乗り物は{self.name}です。")

# 子クラス(Car)の定義、Vehicleクラスを継承
class Car('''(穴埋め)'''):
    def drive(self):		# Carクラス固有のメソッド: 車が走る動作
        print(f"{self.name}が道路を走っています。")

# 子クラス(Motorcycle)の定義、Vehicleクラスを継承
class Motorcycle('''(穴埋め)'''):
    def ride(self):			# Motorcycleクラス固有のメソッド: バイクが走る動作
        print(f"{self.name}が高速道路を疾走しています。")

# オブジェクトの生成
car = Car("トヨタ")
motorcycle = Motorcycle("ハーレー")

# 親クラスのメソッドを使って名前を表示
car.'''(穴埋め)'''()			# ここではCarクラスがVehicleクラスからintroduceメソッドを継承している
motorcycle.'''(穴埋め)'''()	# Motorcycleクラスも同様に継承している

# CarクラスとMotorcycleクラスそれぞれの固有メソッドを使用
car.'''(穴埋め)'''()	# Carクラスの固有メソッド
motorcycle.ride()	# Motorcycleクラスの固有メソッド

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

解答例|車両継承ベーシックプログラム

例えば以下のようなプログラムが考えられます。

Q
正解コード
# 親クラス(Vehicle)の定義
class Vehicle:
    def __init__(self, name):	# コンストラクタで車両の名前を設定
        self.name = name
    def introduce(self):	# 親クラスのメソッド: 車両の名前を表示
        print(f"この乗り物は{self.name}です。")

# 子クラス(Car)の定義、Vehicleクラスを継承
class Car(Vehicle):
    def drive(self):		# Carクラス固有のメソッド: 車が走る動作
        print(f"{self.name}が道路を走っています。")

# 子クラス(Motorcycle)の定義、Vehicleクラスを継承
class Motorcycle(Vehicle):
    def ride(self):			# Motorcycleクラス固有のメソッド: バイクが走る動作
        print(f"{self.name}が高速道路を疾走しています。")

# オブジェクトの生成
car = Car("トヨタ")
motorcycle = Motorcycle("ハーレー")

# 親クラスのメソッドを使って名前を表示
car.introduce()			# ここではCarクラスがVehicleクラスからintroduceメソッドを継承している
motorcycle.introduce()	# Motorcycleクラスも同様に継承している

# CarクラスとMotorcycleクラスそれぞれの固有メソッドを使用
car.drive()			# Carクラスの固有メソッド
motorcycle.ride()	# Motorcycleクラスの固有メソッド

解答例の解説|車両継承ベーシックプログラムの考え方

解答例の詳細解説は以下の通りです。

Q
詳細解説

親クラスの定義

# 親クラス(Vehicle)の定義
class Vehicle:
    def __init__(self, name):	# コンストラクタで車両の名前を設定
        self.name = name
    def introduce(self):	# 親クラスのメソッド: 車両の名前を表示
        print(f"この乗り物は{self.name}です。")

ここではすべての車両に共通する土台となる親クラスを作っています。
インスタンスを作るときに受け取った名前を、オブジェクト内部の情報として保存します。
さらに、その保存した名前を使って「この乗り物は〇〇です。」と表示する共通の振る舞いを用意しています。
これにより後で作る子クラスは同じ仕組みをそのまま受け継ぎ、重複なく名前の扱いや紹介処理を利用できます。
ポイントはインスタンス自身を指すキーワードを使って、受け取った値を属性として保持し、メソッドから参照できるようにしていることです。

子クラスの定義

# 子クラス(Car)の定義、Vehicleクラスを継承
class Car(Vehicle):
    def drive(self):		# Carクラス固有のメソッド: 車が走る動作
        print(f"{self.name}が道路を走っています。")

# 子クラス(Motorcycle)の定義、Vehicleクラスを継承
class Motorcycle(Vehicle):
    def ride(self):			# Motorcycleクラス固有のメソッド: バイクが走る動作
        print(f"{self.name}が高速道路を疾走しています。")

ここでは親クラスから性質を受け継いだ子クラスを2つ用意し、それぞれに固有の振る舞いを与えています。
子クラスにすることで、親で定義した名前の保持や紹介の処理はそのまま使えます。
新しく必要なのは、車なら「走る」、バイクなら「疾走する」といった、個別の動作を表すメソッドだけです。
親のコンストラクタをそのまま使えるため、ここでは子クラス側で初期化を作り直す必要はありません。
親から受け継いだ属性はそのまま参照できるので、固有メソッドの中で名前を自然に使える点もポイントです。
こうして「共通部分は親」「違いは子」に分けると、コードの重複が減り、読みやすさと拡張しやすさが高まります。

インスタンス生成

# オブジェクトの生成
car = Car("トヨタ")
motorcycle = Motorcycle("ハーレー")

# 親クラスのメソッドを使って名前を表示
car.introduce()			# ここではCarクラスがVehicleクラスからintroduceメソッドを継承している
motorcycle.introduce()	# Motorcycleクラスも同様に継承している

# CarクラスとMotorcycleクラスそれぞれの固有メソッドを使用
car.drive()			# Carクラスの固有メソッド
motorcycle.ride()	# Motorcycleクラスの固有メソッド

ここでは、子クラスから実際のオブジェクトを作り、親から受け継いだ処理と子クラス特有の処理を続けて実行しています。
インスタンスを作成するときに渡した名前は内部に保存され、親クラスの紹介用メソッドを呼ぶことで、その名前を使ったメッセージが表示されます。
続いて、各クラスに用意してある固有の走行メソッドを呼び出すと、車とバイクそれぞれの振る舞いが確認できます。
メソッド呼び出しは、オブジェクトに対して「ドットでつなぐ」形で行い、実行結果例の順番に呼ぶと同じ出力が得られます。
これにより、継承で受け継いだ共通機能と、子クラスで追加した違いが、1つの流れの中で明確に体験できます。

もっと分かりやすい学習サイトにするために

この記事を読んで「ここが分かりにくかった」「ここが難しかった」等の意見を募集しています。

世界一わかりやすいPython学習サイトにするため、ぜひ 問い合わせフォーム からご意見下さい。

<<前のページ

【Python学習記事のアイキャッチ画像】Lesson5-4 プロパティを理解しよう

Pythonの記事一覧

Python学習カテゴリの親ページ用アイキャッチ画像(テキスト&問題集)、記事一覧へのリンク案内

次のページ>>

【Python学習記事のアイキャッチ画像】Lesson5-6 メソッドのオーバーライドを理解しよう

クラスの継承の疑問解消|FAQと用語のまとめ

初心者がつまずきやすいポイントをFAQとしてまとめ、またよく使う専門用語をわかりやすく整理しました。

理解を深めたいときや、ふと疑問に感じたときに役立ててください。

FAQ|クラスの継承に関するよくある質問

Q
Q1. クラス継承を使うメリットは何ですか?

コードの再利用性を高め、共通機能を親クラスにまとめることで、プログラム全体の保守性と可読性が向上します。

Q
Q2. クラス継承とインスタンス化の関係は?

継承された子クラスもインスタンス化が可能で、親クラスの機能を使いつつ、独自の機能を追加することができます。

Q
Q3. クラス継承は複数階層で使えますか?

はい、Pythonでは多階層の継承が可能で、親クラス→子クラス→孫クラスといった設計ができます。

Python用語集|クラスの継承に関する用語一覧

今回の記事で出てきた用語・関数などを一覧で紹介します。

このサイトに出てくる 全てのPython用語をまとめた用語集 も活用してください。

Python用語定義・使い方の概要解説記事へのリンク
クラスデータとその操作(メソッド)をまとめた設計図で、オブジェクト指向プログラミングの基本単位Lesson5-1
クラスの継承既存のクラスの機能を引き継いで新たなクラスを定義する機能。コードの再利用性を高める本記事
親クラス(基底クラス)継承される側のクラスで、共通の属性やメソッドを定義する。派生クラスに機能を提供する本記事
子クラス(サブクラス)親クラスを継承し、機能を引き継いだり拡張・上書きしたりする新しいクラス本記事
super()関数親クラスのメソッドを子クラス内から呼び出すための組み込み関数。特に __init__ の呼び出しに使われる本記事
記事URLをコピーしました