【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…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化
是不是受够了安装了oracle database之后sqlplus的简陋,无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话,配置.bahs_profile后也能解决上下翻页这些,但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可,…...

GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...

Python环境安装与虚拟环境配置详解
本文档旨在为Python开发者提供一站式的环境安装与虚拟环境配置指南,适用于Windows、macOS和Linux系统。无论你是初学者还是有经验的开发者,都能在此找到适合自己的环境搭建方法和常见问题的解决方案。 快速开始 一分钟快速安装与虚拟环境配置 # macOS/…...