クラスを継承する方法

10.2 クラスを継承する方法

実際のソースコードでどのように記述すれば、継承したクラスを作成できるのか説明していきます。

10.2.1 クラスを継承する方法について

まずはクラスを拡張する基本構文を以下に示します。

書式:クラスの継承

    class サブクラス名(スーパークラス名):
        サブクラスに追加するインスタンス
        サブクラスに追加するメソッド
	

凡例:クラスの拡張

    class NotePc(Computer):
    count = 0 #クラス変数

    setUsetype(self):インスタンスメソッド
        …
	

クラスを継承する方法はそれほど難しくありません。凡例を見ても分かるように新しいクラス名の引数に「継承元のクラス名」を指定すれば、これだけでNotePcクラスはComputeクラスの機能全てを受け継ぐこと(継承)ができます。後はComputerクラスにはない、NotePcクラスに必要な変数やメソッドを記述すればよいのです。
継承により若干記述方法に制約がつく場合と、スーパークラスを扱う仕組みが増えてはいますが、基本的なクラスの定義方法はこれまで学習してきた方法と変わりありません。制約がつく場合とスーパークラスを扱う仕組みについては後程解説を行っていきます。

ポイント

  • クラスの宣言時にクラスを継承しスーパークラスを指定することができる。作られたクラスはサブクラスとなります。それでは実際に既存のクラスから継承して新しいクラスを作成したプログラムを紹介していきます。

10.2.2 既存のクラスの機能を継承した新しいクラスを作成する

既存のクラス「Computer1」の機能を継承した新しいクラス「NotePc1」を作成します。クラスを拡張する方法について学習しましょう。

ソースコード

ソース・フォルダー: /Desktop/Python基礎講座
ファイル名: 第10章.ipynb
アクセスURL: http://localhost:8888/notebooks/Desktop/Python基礎講座/第10章.ipynb

    class Computer:

        num = 0
        def __init__(self,name='windoes',memory='89'):
            self.name = name
            self.memory = memory
            Computer.num += 1
            print('スーパークラスのコンストラクタが実行されました。')

        def osMemory(self):
            print('【作成されたPCの内容】')
            print('・os名:',self.name)
            print('・メモリー:',self.memory,'GB')

        @classmethod
        def checknum(cls):
            print('【メンテナンスチェック】')
            if cls.num > 2:
                print('作成台数は',cls.num,'台ですので、メンテナンスを実施します。')
            else:
                print('作成台数は',cls.num,'台です。メンテナンスは不要です。')

    class notePc(Computer):

        model = 'notePc'

        def subMethod(self):
            print('【スーパークラスの継承したインスタンス変数】')
            print('name',self.name)
            print('os',self.memory)
            print('【サブクラスで定義したクラス変数】')
            print('model',notePc.model)
	

実行結果

既存のクラスの機能を継承した新しいクラスを定義しただけの為、実行結果は無し

解説

継承もとのComputerクラスはスーパークラスとなり、NotePcクラスは、Computerクラスの機能を継承したサブクラスになります。
23行目のクラス名の引数に「Computer」と記述することでComputerクラスを継承します。

    class Computer:
	

25行目にはこのクラスで利用する、クラス変数modelを定義しています。

    model = 'notePc'
	

27~32行目はこのクラスのメソッドを定義しており、このメソッド内で親クラスのインスタンス変数のname、memoryを呼び出し、notePcのクラス内で宣言したクラス変数modelを呼び出しております。

    def subMethod(self):
        print('【スーパークラスの継承したインスタンス変数】')
        print('name',self.name)
        print('os',self.memory)
        print('【サブクラスで定義したクラス変数】')
        print('model',notePc.model)
	

クラスを継承する宣言があるだけで、クラスの定義方法は変わっていないことが確認できます。これでComputerクラスの機能を継承したNotePcクラスが作成できたことになります。

図 10.2.1: クラスの継承

次項で継承した新しいサブクラスから、継承した機能や自身の機能を利用したプログラムを紹介します。

10.2.3 サブクラスのインスタンスを作成して利用するプログラム

拡張して作成したサブクラスをインスタンス化して、継承した機能と独自の機能を利用して動作することを確認します。

ソースコード

ソース・フォルダー: /Desktop/Python基礎講座
ファイル名: 第10章.ipynb
アクセスURL: http://localhost:8888/notebooks/Desktop/Python基礎講座/第10章.ipynb

    class Computer:

        num = 0
        def __init__(self,name='windoes',memory='89'):
            self.name = name
            self.memory = memory
            Computer.num += 1
            print('スーパークラスのコンストラクタが実行されました。')

        def osMemory(self):
            print('【作成されたPCの内容】')
            print('・os名:',self.name)
            print('・メモリー:',self.memory,'GB')

        @classmethod
        def checknum(cls):
            print('【メンテナンスチェック】')
            if cls.num > 2:
                print('作成台数は',cls.num,'台ですので、メンテナンスを実施します。')
            else:
                print('作成台数は',cls.num,'台です。メンテナンスは不要です。')

    class notePc(Computer):

        model = 'notePc'

        def subMethod(self):
            print('【スーパークラスの継承したインスタンス変数】')
            print('name',self.name)
            print('os',self.memory)
            print('【サブクラスで定義したクラス変数】')
            print('model',notePc.model)

    npc = notePc()
    #サブクラスのインスタンスメソッドを呼び出し
    npc.subMethod()
    #継承元のインスタンスメソッドを呼び出し
    npc.osMemory()
    #継承元のクラスメソッドを呼び出し
    npc.checknum()
	

実行結果

	スーパークラスのコンストラクタが実行されました。
	【スーパークラスの継承したインスタンス変数】
	name windoes
	os 89
	【サブクラスで定義したクラス変数】
	model notePc
	【作成されたPCの内容】
	・os名: windoes
	・メモリー: 89 GB
	【メンテナンスチェック】
	作成台数は 1 台です。メンテナンスは不要です。
	

解説

34行目でComputerクラスの機能を継承したNotePcクラスのインスタンス化を行っています。

    npc = notePc()
	

Computerクラスのコンストラクタも継承されるため、この時点でComputerクラスのコンストラクタが読み込まれるため、この段階で「スーパークラスのコンストラクタが実行されました。」と出力されます。

36行目で、NotePcクラスのsubMethod()メソッドを呼び出しております。

    npc.subMethod()
	

このメソッドは、Computerクラスで宣言したインスタンス変数のname、memory、NotePcクラスのクラス変数modelを呼び出す処理を行います。

【36行目の出力結果】
	【スーパークラスの継承したインスタンス変数】
	name windoes
	os 89
	【サブクラスで定義したクラス変数】
	model notePc
	

出力結果からサブクラス(NotePc)からスーパークラス(Computer)のインスタンス変数や、サブクラス自身のクラス変数が出力されることがわかります。

38行目でスーパークラス(Computer)のインスタンスメソッド(osMemory)を呼び出しております。

    npc.osMemory()
	

こちらも出力結果からサブクラス(NotePc)からスーパークラス(Computer)のインスタンスメソッドが呼び出しできていることが確認できます。

【38行目の出力結果】
	【作成されたPCの内容】
	・os名: windoes
	・メモリー: 89 GB
	

最後に39行目でスーパークラスのクラスメソッドchecknum()を呼び出してます。

    npc.checknum()
	

こちらも実行結果からも分かるように、サブクラスから継承元のスーパークラスのクラスメソッドが呼び出せていることが確認できます。

【38行目の出力結果】
	【メンテナンスチェック】
	作成台数は 1 台です。メンテナンスは不要です。
	

ポイント

  • サブクラスはスーパークラスの変数とメソッドを引き継ぎ、さらに機能を追加できる。

今回のプログラムの実行結果から気になる点があります。それは今回のプログラムではNotePcクラスのインスタンス化のみを行っているはずなのに、継承元のComputerクラスのコンストラクタが呼び出されている点です。
コンストラクタはインスタンス生成と同時に読み込まれるもので、サブクラスはスーパークラスのコンストラクタを引き継ぐため、このような動作が行われますが、スーパークラス独自のコンストラクタを設けることはできないのでしょうか?
この点につきましては次の項以降で説明していきます。


NEXT>> 10.3 オーバーライドについて