天天看點

記錄多繼承中Diamond Problem的一種解法(MRO算法)

1. 原理介紹

本小節引用自:《JavaScript中的“多繼承”》

假設現在有這樣的多繼承結構:
記錄多繼承中Diamond Problem的一種解法(MRO算法)

其中 merge 的規則如下:

1. 取出第一個序列的 head

2. 如果,該 head 不在其它序列的 tail中,則把這個 head 添加到結果中并從所有的序列中移除它

3. 否則,用下一個序列的 head 重複上一步

4. 直到所有序列中的所有元素都被移除(或者無法找到一個符合的head)

最後我們來計算下圖3中各個類的線性順序:

L(O) = O

L(X) = X + L(O) = XO

L(Y) = Y + L(O) = YO

L(A) = A + merge(L(X), L(Y), XY)

= A + merge(XO, YO, XY)

= AX + merge(O, YO, Y)

= AXY + merge(O, O)

= AXYO

L(B) = B + L(Y) = BYO

L(C) = C + merge(L(A), L(B), AB)

= C + merge(AXYO, BYO, AB)

= CA + merge(XYO, BYO, B)

= CAX + merge(YO, BYO, B)

= CAXB + merge(YO, YO)

= CAXBYO

上述多繼承結構的 python 示例可參見 https://glot.io/snippets/ez5bqslav2 輸出了 C 這個類的 MRO 即 C A X B Y O

當然C3算法也有 bad case,會導緻上述的 merge 在中途失敗,也就是無法求出 MRO 的 case。關于 MRO 的更多細節可參考 The Python 2.3 Method Resolution Order 總之不推薦設計出過于複雜的多繼承結構 =_=

2. MRO的邏輯實作

  1. 把繼承序列豎着寫

    A

    X B

    Y Y A

    O O B

  2. 把繼承序列拼接為一行

    A X B Y Y A O O B

  3. 從前往後,删除已經出現過的元素

    A X B Y O

繼續閱讀