当前位置: 首页 > 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}
}

相关文章:

【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 &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 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 &#xff0c;ramgpiotimerpower 明确哪些资源是项目开发需要的 认真理解相关资料模块 开始编程 编写特别的验证程序&#xff08;项目不紧&#xff09;按照自己的理解编写&#xff08;老司机&#xff0c;时间紧张&#xff09; 掌握MCU基本功能 定时器 固…...

XSS-DOM

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

uniapp去掉页面导航条

在pages.json文件中&#xff0c;globalStyle中添加 ”app-plus“:{"titleNView":false }...

MySQL数据库专栏(三)数据库服务维护操作

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

【QT】基于UDP/TCP/串口 的Ymodom通讯协议客户端

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

超详细!!!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…...

【排序篇】实现快速排序的三种方法

&#x1f308;个人主页&#xff1a;Yui_ &#x1f308;Linux专栏&#xff1a;Linux &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;数据结构专栏&#xff1a;数据结构 文章目录 1 交换排序1.1 冒泡排序1.2 快速排序1.2.1 hoare版本1.2.2 挖坑法1.2.3 前后指针…...

Java 标识符(详解)

文章目录 一、简介二、命名规则三、命名规范 一、简介 在 Java 中&#xff0c;用于给变量、类、方法等命名的符号组合&#xff0c;我们称之为Java标识符&#xff0c;它就像是给这些编程元素贴上的独特标签&#xff0c;以便在程序中能够准确地引用和操作它们。 二、命名规则 标…...

2024年,有哪些优质的计算机书籍推荐?

在2024年&#xff0c;计算机领域的新书层出不穷&#xff0c;涵盖了从基础理论到前沿技术的多个方面。以下是今年出版的几本备受关注的计算机新书。 1. AI与机器学习类 1、深度学习详解 1.李宏毅老师亲笔推荐&#xff0c;杨小康、周明、叶杰平、邱锡鹏鼎力推荐! 2.数百万次播…...

Python基础知识点--总结

1. 注释 注释用于提高代码的可读性&#xff0c;在代码中添加说明文字&#xff0c;使代码更容易理解。 单行注释&#xff1a;使用 # 符号开头&#xff0c;注释内容在符号之后的行内。多行注释&#xff1a;使用三引号&#xff08; 或 """&#xff09;包裹注释内…...

高效记录与笔记整理的策略:工具选择、结构设计与复习方法

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…...

Request重复读的问题

换了新工作都有时间写文章&#xff0c;每天也是加班到很晚&#xff0c;也不是工作内容多&#xff0c;主要是还是效率低&#xff0c;要考虑多干的很心累。 一、关于request重复读的问题&#xff0c;从源码的角度来分析 为什么他不能重复读 跳转 再看源码前可能需要一些基础的…...

Linux学习第60天:Linux驱动开发的一些总结

今天是Linux驱动开发的最后一个章节&#xff0c;题目中标明是60天完成的&#xff0c;其实在实际学习及笔记的整理中不止是60天。中间有过断更&#xff0c;有时断更的时间还是挺长的。这是在整个Linux驱动开发学习中最不满意的地方。 题目为Linux学习&#xff0c;其实这个题目有…...

OPP || 继承和抽象类 || 访问控制

OPP面向对象程序设计 数据抽象&#xff1a;类的接口声明和定义实现分离继承&#xff1a;类构成的&#xff08;树型&#xff09;层次关系动态绑定&#xff1a;忽略相似类型区别&#xff0c;用统一的方式使用 基类派生类&#xff1a; 继承&#xff1a;类名 冒号 访问说明符 …...

蓝牙音视频远程控制协议(AVRCP) command跟response介绍

零.声明 本专栏文章我们会以连载的方式持续更新&#xff0c;本专栏计划更新内容如下&#xff1a; 第一篇:蓝牙综合介绍 &#xff0c;主要介绍蓝牙的一些概念&#xff0c;产生背景&#xff0c;发展轨迹&#xff0c;市面蓝牙介绍&#xff0c;以及蓝牙开发板介绍。 第二篇:Trans…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...