|
===================================== 〔語彙分解〕的な部分一致の検索結果は以下の通りです。 ・ 菱形 : [ひしがた] (n) diamond shape ・ 形 : [けい, かたち, ぎょう] 1. (suf) shape 2. form 3. type ・ 継承 : [けいしょう] 1. (n,vs) inheritance 2. succession 3. accession
菱形継承問題(ひしがたけいしょうもんだい、)は、多重継承を伴うオブジェクト指向プログラミング言語において、クラス A を2つのクラス B と C が継承し、B と C の両方をクラス D が継承する際に発生するあいまいさを指す用語である。クラス D にあるメソッドが A で定義された(かつ D においてオーバーライドされていない)メソッドを呼び出すとしたとき、B と C がそのメソッドを異なった形でオーバーライドしていたら、D は B と C のどちらのメソッドを継承するのか、という問題である。 例えば、クラス Button は クラス Rectangle(見た目のため)と Mouse(マウスイベントのため)を継承し、Rectangle も Mouse も Object クラスを継承しているとする。ここで Button オブジェクトが equals メソッドを呼び出し、Button クラス自体にはそのメソッドは定義されていないとする。Rectangle と Mouse にはオーバーライドされた equals メソッドがそれぞれ定義されているとしたら、どちらを呼び出すべきか? これが「菱形; diamond」問題と呼ばれるのは、クラス継承図の形状が菱形になるためである。クラス A が頂上にあり、B と C がそれぞれそこから枝分かれし、D がその2つの枝を再び1つにすることで、全体として菱形を形成する。 いかにも難問のような雰囲気があるが、継承によるオブジェクト指向設計ではごくあたりまえに考えられうる形である。たとえば、ドローソフトにおける各種の図形を扱うクラスを設計している、としよう。「図形」→「四角形」→「平行四辺形」と派生させ、「平行四辺形」から「長方形」や「菱形」を派生させる。ここで「正方形」は長方形であると同時に菱形でもある、という形で菱形継承があらわれる(なお、ここでいう図形の菱形は、英: rhombus であり「ダイヤモンド」ではなく、日本語の偶然である)。またストリームなどでも、「読み出しストリーム」「書き込みストリーム」の両方を継承した「読み書きストリーム」といった形であらわれる。 == 対処法 == プログラミング言語ごとにこの問題への対処法は異なる。 * C++ では、デフォルトでは個々の継承経路を独立して扱う。従って D オブジェクトには実際には2つの独立した A オブジェクトが内包され、A のメンバの使用は適切に行われる。A から B への継承と A から C への継承が共に "virtual "(例えば "class B : virtual public A ")である場合、C++ はこれを特別に扱い、1つの A オブジェクトだけを生成し、A のメンバは正しく動作する。仮想継承と仮想でない継承が混在した場合、唯一の仮想の A と個々の仮想でない継承経路ごとの A が存在することになる。* Common Lisp では、合理的なデフォルトの動作とそれをオーバーライドする能力を提供する。デフォルトでは、引数のクラス指定が最も具体的なメソッドが選択され、サブクラスの定義内でスーパークラスが指定された順番に従う。しかし、プログラマはこれをオーバーライドでき、メソッドごとの解決順序を指定したり、メソッド結合規則を指定したりできる。 * Eiffel では、ディレクティブを改名して選択することでこの問題を回避する。すなわち、上位クラスのメソッドを下位オブジェクトが使うときは明示的に指定する。これによって基底クラスのメソッド群がサブクラス間で共有でき、個々のクラスが基底クラスの個別のコピーを持っているように見なせる。 * Perl や Io では、継承するクラス群を順序リストで指定することで対処する。上述の例で言えば、クラス B の上位の方がクラス C の上位の前にチェックされるので、A のメソッドは B を通してのみ継承される。* 2.1 以前の Python では、多重継承に対し、深さ優先-左から右の順でクラスのリストを生成する。Python 2.2 で導入され Python 3 では統一された、新スタイルクラス〔http://www.python.org/doc/newstyle/〕では、全てのクラスは共通の基底クラス object から派生させるため、菱形継承への対処が重要になった。この時に同時に導入された順序は 2.2 でのみの採用にとどまったためここでは説明しない〔詳細は http://python-history.blogspot.jp/2010/06/method-resolution-order.html を参照のこと〕。Python 2.3 以降および Python 3 では C3(w:C3 linearization)が採用された〔http://www.python.org/download/releases/2.3/mro/〕。抄文引用元・出典: フリー百科事典『 ウィキペディア(Wikipedia)』 ■ウィキペディアで「菱形継承問題」の詳細全文を読む 英語版ウィキペディアに対照対訳語「 Multiple inheritance 」があります。 スポンサード リンク
|