ToB企服应用市场:ToB评测及商务社交产业平台
标题:
【Solidity】继承
[打印本页]
作者:
徐锦洪
时间:
2024-8-19 22:08
标题:
【Solidity】继承
继承
Solidity 中使用 is 关键字实现继承:
contract Father {
function getNumber() public pure returns (uint) {
return 10;
}
function getNumber2() public pure virtual returns (uint) {
return 20;
}
}
contract Son is Father {}
复制代码
现在 Son 就可以调用 Father 的 getNumber、getNumber2 方法啦
函数重写
对于父合约中用 virtual 修饰的方法,可以在子合约中改用 override 修饰 并重写方法的内容:
contract Father {
function getNumber() public pure returns (uint) {
return 10;
}
function getNumber2() public pure virtual returns (uint) {
return 20;
}
}
contract Son is Father {
function getNumber2() public pure override returns (uint) {
return 40;
}
}
复制代码
多级继承
contract Father {
function getNumber() public pure returns (uint) {
return 10;
}
function getNumber2() public pure virtual returns (uint) {
return 20;
}
function getNumber3() public pure virtual returns (uint) {
return 30;
}
}
contract Son is Father {
function getNumber2() public pure override returns (uint) {
return 40;
}
// 用 virtual 和 override 同时修饰方法
function getNumber3() public pure virtual override returns (uint) {
return 50;
}
}
contract GrandSon is Son {
function getNumber3() public pure override returns (uint) {
return 60;
}
}
复制代码
多重继承
在 Solidity 中,继承次序通过 C3 线性化算法确定。这个算法确保继承关系是一个有向无环图(DAG),并逼迫一个特定的继承次序。
demo1
:
X
/ |
Y |
\ |
Z
复制代码
根据 C3 线性化算法,继承次序是从最底层的合约开始,逐层向上合并继承路径。详细步调如下:
从最底层合约 Z 开始:
Z 继承自 Y 和 X。
继承次序:[Z, Y, X]。
合并继承路径:
Y 继承自 X。
继承次序:[Y, X]。
最终继承次序:
合并 Z 的继承次序 [Z, Y, X] 和 Y 的继承次序 [Y, X]。
确保每个合约只出现一次,而且遵循继承关系。
最终继承次序为:[Z, Y, X]。
contract X {
function foo() public virtual returns (string memory) {
return "X";
}
}
contract Y is X {
function foo() public virtual override returns (string memory) {
return "Y";
}
}
// 根据继承顺序, 先 X 后 Y; 若遇平级, 则顺序随意
contract Z is X, Y {
// override 里面的顺序无所谓
function foo() public pure override(Y, X) returns (string memory) {
return "Z";
}
}
复制代码
demo2
:
X
/ \
Y A
| |
| B
\ /
Z
复制代码
根据 C3 线性化算法,继承次序是从最底层的合约开始,逐层向上合并继承路径。详细步调如下:
从最底层合约 Z 开始:
Z 继承自 Y 和 B。
继承次序:[Z, Y, B]。
合并继承路径:
Y 继承自 X。
B 继承自 A,A 继承自 X。
继承次序:[Y, X] 和 [B, A, X]。
最终继承次序:
合并 Z 的继承次序 [Z, Y, B] 和 Y 的继承次序 [Y, X] 以及 B 的继承次序 [B, A, X]。
确保每个合约只出现一次,而且遵循继承关系。
最终继承次序为:[Z, Y, B, A, X]。
contract X {
function foo() public virtual returns (string memory) {
return "X";
}
}
contract Y is X {
function foo() public virtual override returns (string memory) {
return "Y";
}
}
contract A is X {
function foo() public virtual override returns (string memory) {
return "A";
}
}
contract B is A {
function foo() public virtual override returns (string memory) {
return "B";
}
}
contract Z is Y, B {
function foo() public pure override(Y, B) returns (string memory) {
return "Z";
}
}
复制代码
调用父合约的构造函数
contract A {
string public name;
constructor(string memory _name) {
name = _name;
}
}
contract B {
uint public number;
constructor(uint _number) {
number = _number;
}
}
// demo 1 - 在构造函数后面调用基类构造函数
contract C is A, B {
constructor(string memory _name, uint _number) A(_name) B(_number) {}
}
// demo 2 - 在合约定义时调用基类构造函数
contract D is A("Hello"), B(42) {}
// demo 3 - 混合使用 demo 1 和 2 的方法
contract E is A("Hello"), B {
constructor(uint _number) B(_number) {}
}
复制代码
构造函数的调用次序:先继承的父合约 → 后继承的父合约 → 当前合约
以是,demo 1 是 A → B → C、 demo 2 是 A → B → D、 demo 3 是 A → B → E
调用父合约的方法
contract A {
event Log(string message);
function func() public virtual {
emit Log("A.func");
}
}
contract B is A {
function func() public virtual override {
emit Log("B.func");
// 方法 1 - 通过 super 调用
super.func(); // A
}
}
contract C is A {
function func() public virtual override {
emit Log("C.func");
// 方法 2 - 通过合约调用
A.func(); // A
}
}
contract D is B, C {
// 方法 1 和方法 2 的区别
function func() public override(B, C) {
C.func(); // C - A
B.func(); // B - A
A.func(); // A
}
function funcD() public {
super.func(); // C - B - A
}
}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4