当前位置: 首页 > news >正文

【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 线性化算法,继承顺序是从最底层的合约开始,逐层向上合并继承路径。具体步骤如下:

  1. 从最底层合约 Z 开始:

    • Z 继承自 YX
    • 继承顺序:[Z, Y, X]
  2. 合并继承路径:

    • Y 继承自 X
    • 继承顺序:[Y, X]
  3. 最终继承顺序:

    • 合并 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 线性化算法,继承顺序是从最底层的合约开始,逐层向上合并继承路径。具体步骤如下:

  1. 从最底层合约 Z 开始:

    • Z 继承自 YB
    • 继承顺序:[Z, Y, B]
  2. 合并继承路径:

    • Y 继承自 X
    • B 继承自 AA 继承自 X
    • 继承顺序:[Y, X][B, A, X]
  3. 最终继承顺序:

    • 合并 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 - AB.func(); // B - AA.func(); // A}function funcD() public {super.func(); // C - B - A}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Django Signals
  • 【html+css 绚丽Loading】 - 000003 乾坤阴阳轮
  • 【算法/学习】双指针
  • 25考研计算机组成原理复习·3.5高速缓冲存储器
  • bootchart抓Android系统启动各阶段性能数据
  • 【微服务】Spring Cloud Alibaba 的介绍以及和主要功能
  • Type-C接口主要的几个功能引脚及功能
  • 【题目/训练】:双指针
  • 云主机部署 TiDB 测试集群
  • 景联文科技:一文详解如何构建高质量SFT数据
  • java基础03——Arrays.asList与ArrayList的区别(基本概念、用法、使用场景)
  • 24/8/17算法笔记 模仿学习算法
  • Spring中AbstractAutowireCapableBeanFactory
  • Unity3D开发之OnCollisionXXX触发条件
  • Spring Boot集成Devtools实现热更新?
  • [LeetCode] Wiggle Sort
  • 【Amaple教程】5. 插件
  • 【RocksDB】TransactionDB源码分析
  • Angular4 模板式表单用法以及验证
  • C++入门教程(10):for 语句
  • If…else
  • Javascripit类型转换比较那点事儿,双等号(==)
  • JavaScript实现分页效果
  • Python3爬取英雄联盟英雄皮肤大图
  • Redux系列x:源码分析
  • vagrant 添加本地 box 安装 laravel homestead
  • 从伪并行的 Python 多线程说起
  • 欢迎参加第二届中国游戏开发者大会
  • 缓存与缓冲
  • 计算机在识别图像时“看到”了什么?
  • 老板让我十分钟上手nx-admin
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 小李飞刀:SQL题目刷起来!
  • 关于Android全面屏虚拟导航栏的适配总结
  • ​LeetCode解法汇总518. 零钱兑换 II
  • ​用户画像从0到100的构建思路
  • #includecmath
  • #laravel 通过手动安装依赖PHPExcel#
  • #php的pecl工具#
  • #微信小程序:微信小程序常见的配置传值
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (~_~)
  • (C#)获取字符编码的类
  • (CVPRW,2024)可学习的提示:遥感领域小样本语义分割
  • (二)linux使用docker容器运行mysql
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (论文阅读30/100)Convolutional Pose Machines
  • (三)mysql_MYSQL(三)
  • (四)事件系统
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (自用)交互协议设计——protobuf序列化
  • *Django中的Ajax 纯js的书写样式1