Java.use(better, Python)《12》継承に警鐘を鳴らす(その玖)

記事一覧《こちらに移動中です》2006年6月20日 (火)

Java.use(better, Python)  # Stairway to Real Agile World

《12》継承に警鐘を鳴らす(その玖)《Jython2.5.0》

《著》後藤いるか・河野かえる・伊藤うさぎ・小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
第1版♪2003/05/23

■ 概要

継承の概念を実現するのに、いくつかの方法があります。そのひとつが、新しいクラスを定義した後で、クラスで定義されたメソッドとは別に、そのインスタンスに固有のメソッドを再定義するというものです。

継承には、
 (1)構造継承
 (2)機能継承
 (3)プロトコル継承
があって、さらに(2)機能継承は、次の3つに分類されます。
 (2a)親子関係にあるクラス間の継承
 (2b)親子関係にないクラス間の継承
 (2c)クラスとインスタンス間の継承
ともすると、Java/C# などでは、狭義の(2a)に関心が寄せられがちです。しかし、純粋な OOP の世界では、その限りではありません。では、広義の継承は、どのように実現するのでしょうか。

■ 関連記事
  •  

前の記事次の記事

《12》継承に警鐘を鳴らす(その玖)

■ 二分木の例

単純な二分木を使って、インスタンスに固有のメソッドを定義する事例を紹介します。

class Tree: pass
null = Tree()
null.__str__       = lambda  : ""
null.displayString = lambda n: ""
null.size          = lambda  : 0

変数 null を参照すると、Tree のインスタンスが得られます。同じクラスの他のインスタンスと違って、固有のメソッド関数を持ちます。メソッド関数 __str__ は、引数を持たず、空の文字列をリターンとします。メソッド関数 displayString は、引数 n を持ち、空の文字列をリターンとします。メソッド関数 size は、引数を持たず、0 をリターンとします。つまり、null は、空の部分木を表すもので、その文字列表現を持たず、その大きさ(節の数)0 はとなります。

※ null は、Tree のインスタンスなので、有効なメソッド呼び出しに対して、例外を生じません。他のインスタンスとの違いは、有効なメソッド呼び出しに対して、実際には何も(必要のない作業を)しないということです。□

print null.__dict__
# -------------------------------- Output --
{'displayString':  at 0x3b24d70>, '__str__':  at 0x17cd5f0>, 'size':  at 0x3b2daf0>}

null のインスタンス属性 __dict__ は、メソッド辞書オブジェクトを束縛します。この辞書には、3つのメソッド関数と同名のキー属性を保持しているのが分かります。これらのキー項目と同じメソッド呼び出しに対しては、クラス辞書に登録されたメソッド関数ではなく、インスタンス辞書に登録されたメソッド関数が適用されます。

print t.__class__.__dict__
# -------------------------------- Output --
{'reprString': , '__module__': 'BinaryTree', '__str__': , '__doc__': None, 'displayString': , 'display': , '__init__': , 'size': }

変数 t を参照すると、Tree のインスタンスが得られます。同じクラスの他のインスタンスと同じ、共通のメソッド関数を持ちます。メソッド関数 __str__ は、部分木の文字列表現を得ます。メソッド関数 displayString は、display の補助関数として機能します。メソッド関数 size は、部分木の大きさ(節の数)を得ます。

print t.__dict__
# -------------------------------- Output --
{'right': , 'value': 0, 'left': }

t のインスタンス属性 __dict__ は、属性辞書オブジェクトを束縛します。この辞書には、3つのインスタンス属性と同名のキー属性を保持しているのが分かります。これらのキー項目と同じ属性を参照すると、インスタンス辞書に登録された値項目が束縛するオブジェクト(値)が得られます。

t = Tree()
t.left = Tree(1)
t.right = Tree(2)
print t
# -------------------------------- Output --
0(1(,),2(,))

文 print t を実行すると、変数 t が束縛するオブジェクトに対して、メソッド関数__str__ が適用され、部分木の文字列表現が出力されます。これは、print `t` と同等です。
==================================
後藤いるか+伊藤うさぎ 著 ◆ 監修:小泉ひよ子とタマゴ倶楽部

更新♪2009/08/02