1. 原理介紹
本小節引用自:《JavaScript中的“多繼承”》
假設現在有這樣的多繼承結構:
其中 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的邏輯實作
-
把繼承序列豎着寫
A
X B
Y Y A
O O B
-
把繼承序列拼接為一行
A X B Y Y A O O B
-
從前往後,删除已經出現過的元素
A X B Y O