- 公開日: 2018年07月28日
【Python入門】クラスの継承についてやさしく解説
継承、オブジェクト指向を実行する上で欠かせない機能ですね。
今回は、Pythonの継承についてご紹介。
恐らく継承を学習される方は、ある程度Pythonを体験していると思いますので、コードメインの記事としました。
コードのコピペ、アレンジを経て、継承マスターにお役立て下さい。
- 【必要な事前知識】
関数、変数、モジュール、クラス
【Python入門】クラスの継承についてやさしく解説
継承とは
継承(Inheritance)は、クラスの中でよく使われる機能の一つで、クラス機能を再利用したり追加できるとてもパワフルな機能。 TensorFlowやFlaskといったフレームワーク系でもよく使われていますね。 今回は、
- 簡単な継承機能
- スーパークラスを使った継承機能
- 継承の継承
- ちょっと実践的な継承
- 複数のクラスをまとめて継承
といった継承の基礎的な部分をコード中心にご紹介していきます。
Pythonの継承を体験【簡単編】
ファイル名 fish.py
class Fish:
def __init__(self, name, build="ほね", eyelids=False):
self.name = name
self.build = build
self.eyelids = eyelids
def swim(self):
print("こちらの魚は泳ぎます")
def swim_back(self):
print("こちらの魚は後ろ向きにも泳ぎます")
class Medaka(Fish):
pass
こちらではクラスの簡単な継承をご紹介。 上記コードの下から2行目で親クラスの Fish を継承しています。
class Medaka(Fish):
class 新規クラス名(継承したいクラス名):
という書き方で継承機能を表現できます。新規クラス名のことを「子クラス」と呼びますね。
最終行の pass は、「親クラスそのままを」という意味。
上記コードで実際にオブジェクトを作成して、メソッドを実行してみますね。
子クラスの Medakaクラスには pass しか書かれていないのに、親クラスのパラメーターやメソッドを継承していることが分かります。
せっかくなので、ただ親クラスを利用するだけでなく、親クラスの内容を上書きする方法もご紹介してみますね。以下のコードを追加。
class Kingyo(Fish):
def __init__(self, name, build="ほね", eyelids=False):
self.name = '金魚ちゃん' + name + 'だよ'
self.build = build + ' かな'
self.eyelids = eyelids
<< 実行結果 >>
- 親クラスの内容を上書きすべく Kingyo クラスを設定。
- 親クラスの初期化データをコピーして、データを追加。
- その結果、継承元のデータを上書きして出力。
次は、親クラスに機能追加できる スーパークラス super() を確認していきます。
スーパークラス super() を使った継承を体験
親クラスのメソッドを子クラスでも使いつつ、新たにパラメーターやメソッドを追加する場合は、スーパークラス super() が便利。 簡単なスーパークラスの事例を以下にご紹介します。
ファイル名 simple-sample.py
class Cat(object):
def __init__(self, name):
self.name = name
class SuperCat(Cat):
def __init__(self, name, function):
super(SuperCat, self).__init__(name)
self.function = function
sample1 = Cat('ちゃちゃ')
sample2 = SuperCat('ごん', '飛ぶ')
sample3 = SuperCat('みーな','もぐる')
print(sample1.name)
print(sample2.name,sample2.function)
print(sample3.name,sample3.function)
<< 実行結果 >>
まずスーパークラスが登場するのは子クラスで、親クラスから継承したいパラメーターを指定します。 上記コードの場合は、7行目の
super(SuperCat, self).__init__(name)
ですね。 name を継承。 後は特別な処理はなく、メソッドやオブジェクトを作成して、親クラスを利用した子クラスができあがり。
実際にスーパークラスのコードを書いていると、「継承の継承ってできるのかな?」と思ったりしませんか? 継承の継承、試してみましたので以下をご参考下さい。
継承の継承・・・を体験
ある基準となる機能へ段階的に機能を追加したい場合、「継承の継承」で実現できます。
ファイル名 Inheritance_Inheritance.py
class Cat(object):
def __init__(self, name):
self.name = name
class SuperCat(Cat):
def __init__(self, name, function):
super(SuperCat, self).__init__(name)
self.function = function
class GodCat(SuperCat):
def __init__(self, name, function, magic):
super(GodCat,self).__init__(name,function)
self.magic = magic
def power(self):
self.magic = 'マジックパワー!!' + self.function * self.magic
sample1 = Cat('ちゃちゃ')
sample2 = SuperCat('ごん', '飛ぶ')
sample3 = GodCat('だい','癒やす',5)
print(sample1.name)
print(sample2.name,sample2.function)
sample3.power()
print(sample3.name,sample3.magic)
<< 実行結果 >>
段階的にクラスが継承されて、それに合わせてメソッドも継承されていることが分かります。 ちなみに継承の継承なので「孫クラス」という位置づけになりますが、「孫クラス」という言葉は流通していません。
それでは次に、少し実践的な事例をご紹介しますね。
ちょっと実践的な継承事例
これまではとりあえず継承やスーパークラスの雰囲気をお伝えしてきました。 これからご紹介するのは、私がPythonの継承学習で参考になったコードです。Pythonのチュートリアル動画としてはヒットの 18万回以上の再生回数を記録している動画を元にしています。
ファイル名 youtube_oop_2.py
class Employee:
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.email = first + '.' + last + '@email.com'
self.pay = pay
def fullname(self):
return '{} {}'.format(self.first, self.last)
def apply_raise(self):
self.pay = int(self.pay * self.raise_amt)
class Programmer(Employee):
raise_amt = 1.10
def __init__(self, first, last, pay, prog_lang):
super().__init__(first, last, pay)
self.prog_lang = prog_lang
class Manager(Employee):
raise_amt = 1.50
def __init__(self, first, last, pay, employees=None):
super().__init__(first, last, pay)
if employees is None:
self.employees = []
else:
self.employees = employees
def add_emp(self, emp):
if emp not in self.employees:
self.employees.append(emp)
def remove_emp(self, emp):
if emp in self.employees:
self.employees.remove(emp)
def print_emps(self):
for emp in self.employees:
print('雇っているエンジニア:', emp.fullname(), 'さん')
print('対応言語:', emp.prog_lang)
dev_1 = Programmer('Tanaka', 'Tarou', 50000, 'Python')
dev_2 = Programmer('Oshima', 'Takayuki', 60000, 'PHP')
mgr_1 = Manager('Adam', 'Jozee', 60000)
print(mgr_1.fullname())
print(mgr_1.email)
print('基本年収($):', mgr_1.pay)
mgr_1.apply_raise()
print('年間の役職手当($):', mgr_1.pay)
mgr_1.add_emp(dev_1)
mgr_1.print_emps()
<< 実行結果 >>
ちょっと長いコードですが、何が処理されているか検討つきますでしょうか?
上記コードは労働者のステータスを管理するプログラムで、クラス Employee を雛形にプログラマーとマネージャーを管理。
親クラスの Employee に名前とメールアドレス、そして最初の子クラス Programmer で対応言語、もう一つの子クラスで Manager の雇用状況を表現。
こちらのコードでは、プログラマの対応言語やマネージャーの年収が入力されていますが、データベースなどと連携できると活用範囲が広がりそうですね。
複数の継承クラスをまとめて利用
最後に複数のPythonファイルからクラスの継承機能を引用する例をご紹介します。 今回は、本稿でご紹介した fish.py と Inheritance_Inheritance.py の2つのPythonファイルからクラス継承するPythonプログラムを作成してみました。 尚、fish.py と Inheritance_Inheritance.py のファイル内のオブジェクト作成行は、なしにして実行しました。
ファイル名 Add.py
from Inheritance_Inheritance import GodCat
from fish import Medaka
class Main(GodCat, Medaka):
def __init__(self):
super(Main, self).__init__()
cat1 = GodCat('だい','癒やす',5)
cat1.power()
print(cat1.name,cat1.magic)
fish1 = Medaka("メダカ1号")
print(fish1.name)
class CatCat(GodCat):
def __init__(self, name, function, magic, change):
super(CatCat, self).__init__(name, function, magic)
self.change = change + 'に変身だにゃー'
cat2 = CatCat('こんきち','はねる','2','みけねこ')
print(cat2.name, cat2.change)
<< 実行結果 >>
冒頭の from ●● import ●● 文で外部ファイル&外部クラスを読み込み。 そして後は外部クラスを利用してオブジェクトを作成し、メソッドの実行となります。
また外部クラスに機能を追加する場合も今までと同じで、継承を用いた記述でプログラムを実行可能。 上記ではクラス GodCat を継承し、 CatCat という子クラスを作成していますね。
尚、当然のことですがインポートしていない外部クラスは利用できません。 下記のようなエラーがでます。
\AIエンジニアに必要なスキルが身に付く/
まとめ
実際にクラスの継承をプログラミングしてみると、いろいろ試したくなってきますよね。 もし継承以前に「クラス」や「関数」、「引数」などの基礎学習がまだであれば、手っ取り早く CodeCamp で基礎マスターしてみませんか。マンツーマン&オンラインでPython学習もはかどると思いますよ。
- この記事を書いた人
- オシママサラ