【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 - AB.func(); // B - AA.func(); // A}function funcD() public {super.func(); // C - B - A}
}
相关文章:
【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 的 …...

docker 安装mino服务,启动报错: Fatal glibc error: CPU does not support x86-64-v2
背景 docker 安装mino服务,启动报错: Fatal glibc error: CPU does not support x86-64-v2 原因 Docker 镜像中的 glibc 版本要求 CPU 支持 x86-64-v2 指令集,而你的硬件不支持。 解决办法 降低minio对应的镜像版本 经过验证:qu…...

地图相册系统的设计与实现
摘 要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代&a…...
使用vh和rem实现元素响应式布局
示例代码 height: calc(100vh 30rem) vh(Viewport Height):vh是一个相对单位,代表浏览器窗口高度的百分比,例如20vh就是浏览器窗口高度的20%。 rem(root em):rem是通过html根元素…...
螺旋矩阵 II(LeetCode)
题目 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 解题 def generateMatrix(n):matrix [[0] * n for _ in range(n)]top, bottom 0, n - 1left, right 0, n - 1num 1while top <…...
如何快速掌握一款MCU
了解MCU特点 rom ,ramgpiotimerpower 明确哪些资源是项目开发需要的 认真理解相关资料模块 开始编程 编写特别的验证程序(项目不紧)按照自己的理解编写(老司机,时间紧张) 掌握MCU基本功能 定时器 固…...

XSS-DOM
文章目录 源码SVG标签Dom-Clobbringtostring 源码 <script>const data decodeURIComponent(location.hash.substr(1));;const root document.createElement(div);root.innerHTML data;// 这里模拟了XSS过滤的过程,方法是移除所有属性,sanitize…...

uniapp去掉页面导航条
在pages.json文件中,globalStyle中添加 ”app-plus“:{"titleNView":false }...

MySQL数据库专栏(三)数据库服务维护操作
1、界面维护,打开服务窗口找到MySQL服务,右键单击可对服务进行启动、停止、重启等操作。 选择属性,还可以设置启动类型为自动、手动、禁用。 2、指令维护 卸载服务:sc delete [服务名称] 例如:sc delete MySQL 启动服…...

【QT】基于UDP/TCP/串口 的Ymodom通讯协议客户端
【QT】基于UDP/TCP/串口的Ymodom通讯协议客户端 前言Ymodom实现QT实现开源库的二次开发-1开源库的二次开发-2 串口方式实现TCP方式实现UDP方式实现补充:文件读取补充:QT 封装成EXE 前言 Qt 运行环境 Desktop_Qt_5_11_2_MSVC2015_64bit ,基于…...

超详细!!!electron-vite-vue开发桌面应用之引入UI组件库element-plus(四)
云风网 云风笔记 云风知识库 一、安装element-plus以及图标库依赖 npm install element-plus --save npm install element-plus/icons-vue npm i -D unplugin-icons二、vite按需引入插件 npm install -D unplugin-vue-components unplugin-auto-importunplugin-vue-componen…...

【排序篇】实现快速排序的三种方法
🌈个人主页:Yui_ 🌈Linux专栏:Linux 🌈C语言笔记专栏:C语言笔记 🌈数据结构专栏:数据结构 文章目录 1 交换排序1.1 冒泡排序1.2 快速排序1.2.1 hoare版本1.2.2 挖坑法1.2.3 前后指针…...
Java 标识符(详解)
文章目录 一、简介二、命名规则三、命名规范 一、简介 在 Java 中,用于给变量、类、方法等命名的符号组合,我们称之为Java标识符,它就像是给这些编程元素贴上的独特标签,以便在程序中能够准确地引用和操作它们。 二、命名规则 标…...

2024年,有哪些优质的计算机书籍推荐?
在2024年,计算机领域的新书层出不穷,涵盖了从基础理论到前沿技术的多个方面。以下是今年出版的几本备受关注的计算机新书。 1. AI与机器学习类 1、深度学习详解 1.李宏毅老师亲笔推荐,杨小康、周明、叶杰平、邱锡鹏鼎力推荐! 2.数百万次播…...
Python基础知识点--总结
1. 注释 注释用于提高代码的可读性,在代码中添加说明文字,使代码更容易理解。 单行注释:使用 # 符号开头,注释内容在符号之后的行内。多行注释:使用三引号( 或 """)包裹注释内…...

高效记录与笔记整理的策略:工具选择、结构设计与复习方法
✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…...
Request重复读的问题
换了新工作都有时间写文章,每天也是加班到很晚,也不是工作内容多,主要是还是效率低,要考虑多干的很心累。 一、关于request重复读的问题,从源码的角度来分析 为什么他不能重复读 跳转 再看源码前可能需要一些基础的…...
Linux学习第60天:Linux驱动开发的一些总结
今天是Linux驱动开发的最后一个章节,题目中标明是60天完成的,其实在实际学习及笔记的整理中不止是60天。中间有过断更,有时断更的时间还是挺长的。这是在整个Linux驱动开发学习中最不满意的地方。 题目为Linux学习,其实这个题目有…...
OPP || 继承和抽象类 || 访问控制
OPP面向对象程序设计 数据抽象:类的接口声明和定义实现分离继承:类构成的(树型)层次关系动态绑定:忽略相似类型区别,用统一的方式使用 基类派生类: 继承:类名 冒号 访问说明符 …...

蓝牙音视频远程控制协议(AVRCP) command跟response介绍
零.声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。 第二篇:Trans…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...