インナークラス
Pythonではクラスをネストして定義することができ、インナークラス(Inner Class) と言われます。
定義方法は次のように、クラスの内側でクラスを定義するだけです。
code: 0813_inner_class_definition_sample.py
class Outer:
class Inner:
class InnerInner: # 複数階層のネストもOK
pass
インナークラスを使うと次のような利点があります。
従属関係にあるクラスを1つの定義に集約できる
コードの隠蔽
クラス変数へのアクセスが簡単になる
「定義の集約」について言えば、例えば Car と Engine というクラスがあり、Carの定義でEngine を使用しているものの、ユーザがCarを利用するときはEngineを意識する必要がない場合です。
こうしたときは、Engineの定義をCarの内部に記述してしまった方が、プログラムが散逸しないので管理しやすくなります。
これと同じような利点に「コードの隠蔽」があります。Car の内部でしか使わないのであれば、外部に公開する必要がないわけです。
公開するつもりが無いコードが他で利用されてしまい、変更できなくなるということも実際のプログラミングでは起きる問題のひとつです。
「アクセスが簡単」というのは、クラス継承ではスーパークラスやサブクラスの経路を意識してアトリビュートを参照する必要があります。これに対してインナークラスでは、定義が1つのクラスの中にあるため、経路の理解や指定がとても簡単になります。
code: 0814_inner_class_definition.py
class Outer:
def __init__(self):
# インナークラスのインスタンスを作成
self.inner = self.Inner()
self.innerinner = self.inner.InnerInner()
def myprint(self):
print("This is Outer class")
class Inner:
def __init__(self):
self.innerinner = self.InnerInner()
def myprint(self):
print("This is Inner class")
class InnerInner:
def inner_myprint(self, msg):
print("This is multilevel InnerInner class")
print(msg)
# インデントに注目
def inner_myprint(self, msg):
print("This is Inner class")
print(msg)
outer = Outer()
outer.myprint()
inner = outer.Inner()
inner.myprint()
innerinner = inner.InnerInner()
innerinner.inner_myprint("Hello!")
これを実行すると次のようになります。
code: bash
$ python 0814_inner_class_definition.py
This is Outer class
This is Inner class
This is multilevel InnerInner class
Hello!
インナークラスはクラス継承よりも簡単に定義、利用することができます。