第三题(加分题):自学C3 Linearization, 求以下 contract Z 的继承线
- contract O
- contract A is O
- contract B is O
- contract C is O
- contract K1 is A, B
- contract K2 is A, C
- contract Z is K1, K2
L(O) := [O]
L(A) := [A] + merge(L(O), [O])
= [A] + merge([O], [O])
= [A, O]
L(B) := [B, O]
L(C) := [C, O]
L(K1) := [K1] + merge(L(B), L(A), [B, A])
= [K1] + merge([B, O], [A, O], [B, A])
= [K1, B, A, O]
L(K2) := [K2] + merge(L(C), L(A), [C, A])
= [K2] + merge([C, O], [A, O], [C, A])
= [K2, C, A, O]
L(Z) := [Z] + merge(L(K2), L(K1), [K2, K1])
= [Z] + merge([K2, C, A, O], [K1, B, A, O], [K2, K1])
= [Z, K2, C, K1, B, A, O]
From Solidity Document:
Languages that allow multiple inheritance have to deal with several problems. One is the Diamond Problem. Solidity is similar to Python in that it uses “C3 Linearization” to force a specific order in the DAG of base classes. This results in the desirable property of monotonicity but disallows some inheritance graphs. Especially, the order in which the base classes are given in the is directive is important: You have to list the direct base contracts in the order from "most base-like" to "most derived". Note that this order is different from the one used in Python. In the following code, Solidity will give the error “Linearization of inheritance graph impossible”.
在Remix上部署contract Z,然后看控制台输出的log顺序
pragma solidity ^0.4.14;
contract O {
constructor() public {
emit PrintO();
}
event PrintO();
}
contract A is O {
constructor() public {
emit PrintA();
}
event PrintA();
}
contract B is O {
constructor() public {
emit PrintB();
}
event PrintB();
}
contract C is O {
constructor() public {
emit PrintC();
}
event PrintC();
}
contract K1 is A, B {
constructor() public {
emit PrintK1();
}
event PrintK1();
}
contract K2 is A, C {
constructor() public {
emit PrintK2();
}
event PrintK2();
}
contract Z is K1, K2 {
constructor() public {
emit PrintZ();
}
event PrintZ();
}