本文其实不算原创,之前学习eth的时候了解到了Solidity使用的是C3多继承,对于继承的关系不太清楚,便上网了解一下,看了些文章,感觉讲的不够通俗,花了一点点时间来理解了,现在我记下来,方便大家理解
这里先给大家介绍几个概念
C3 算法:MRO是一个有序列表L,在类被创建时就计算出来。
L(Child(Base1,Base2)) = [ Child + merge( L(Base1) , L(Base2) , Base1Base2 )]
L(object) = [ object ]
L的性质:结果为列表,列表中至少有一个元素即类自己。
+ : 添加到列表的末尾,即 [ A + B ] = [ A,B ]
表头: 列表的第一个元素 (列表:ABC,那么表头就是A,B和C就是表尾)
表尾: 列表中表头以外的元素集合(可以为空)
merge 其实就是找不在表尾中出现的表头(有效的表头)。
在网上找到了marge的规则
merge: ① 如果列表空则结束,非空 读merge中第一个列表的表头,
② 查看该表头是否在 merge中所有列表的表尾中。
②-->③ 不在,则 放入 最终的L中,并从merge中的所有列表中删除,然后 回到①中
②-->④ 在,查看 当前列表是否是merge中的最后一个列表
④-->⑤ 不是 ,跳过当前列表,读merge中下一个列表的表头,然后 回到 ②中
④-->⑥ 是,异常。类定义失败。
解个题目大家就懂了
class A extends Object;
class B extends Object;
class C extends Object;
class D extends A,B;
class E extends B,C;
class F extends D,E;
求出F的有序列表L(F);
首先,ABC的都很简单,单继承,既
L(A) = [A,O];
L(B) = [B,O];
L(C) = [C,O];
然后到D,继承了A,B,由介绍概念时的公式得
L(D) = L(D(A,B)) = [ D + merge ( L(A) , L(B) ,AB) ],带入L(A)和L(B)得
= [ D + merge ( [A,O] , [B,O] ,AB) ] 到这里就要开始找有效的表头了,从左往右开始
= [ D,A + merge ( [O] , [B,O] ,B) ] A是表头,这时看到【② 查看该表头是否在 merge中所有列表的表尾中】,所有列表的表尾的集合是 [ O , O , B ],则符合【②-->③ 不在,则 放入 最终的L中,并从merge中的所有列表中删除,然后 回到①中】
= [ D,A ,B+ merge ( [O] , [O] ) ] 接下来是O,但是O在表尾中,不合法,跳的第二个集合[ B , O ],同上发现B是合法的
= [D,A,B,O]
同理可求得:
L(E) = L(E(B,C)) = [ E + marge ( L(B) , L(C) , BC) ]
= [ E + marge ( [B,O] , [C,O] , BC) ]
= [E,B,C,O]
L(F) = L(F(D,E)) = [ F + marge ( L(D) , L(E) , DE)]
= [ F + marge ([D,A,B,O] , [E,B,C,O] , DE)]
= [ F,D + marge ([A,B,O] , [E,B,C,O] , E)]
= [ F,D,A + marge ([B,O] , [E,B,C,O] , E)] (B在第二个集合的表尾中,非法)
= [ F,D,A,E + marge ([B,O] , [B,C,O] )]
= [ F,D,A,E,B + marge ([O] , [C,O] )]
= [ F,D,A,E,B,C + marge ([O] , [O] )]
= [ F,D,A,E,B,C,O ]
得到答案啦,如有错误望指正